提交 ae650216 编写于 作者: haoranc's avatar haoranc

Merge branch 'develop' into fix/TD-5454

...@@ -412,6 +412,7 @@ int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* s ...@@ -412,6 +412,7 @@ int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* s
int32_t tscValidateSqlInfo(SSqlObj *pSql, struct SSqlInfo *pInfo); int32_t tscValidateSqlInfo(SSqlObj *pSql, struct SSqlInfo *pInfo);
int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows);
extern int32_t sentinel; extern int32_t sentinel;
extern SHashObj *tscVgroupMap; extern SHashObj *tscVgroupMap;
extern SHashObj *tscTableMetaInfo; extern SHashObj *tscTableMetaInfo;
......
...@@ -946,3 +946,34 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI ...@@ -946,3 +946,34 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI
return JNI_SUCCESS; return JNI_SUCCESS;
} }
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(JNIEnv *env, jobject jobj,
jobjectArray lines, jlong conn) {
TAOS *taos = (TAOS *)conn;
if (taos == NULL) {
jniError("jobj:%p, connection already closed", jobj);
return JNI_CONNECTION_NULL;
}
int numLines = (*env)->GetArrayLength(env, lines);
char** c_lines = calloc(numLines, sizeof(char*));
for (int i = 0; i < numLines; ++i) {
jstring line = (jstring) ((*env)->GetObjectArrayElement(env, lines, i));
c_lines[i] = (char*)(*env)->GetStringUTFChars(env, line, 0);
}
int code = taos_insert_lines(taos, c_lines, numLines);
for (int i = 0; i < numLines; ++i) {
jstring line = (jstring) ((*env)->GetObjectArrayElement(env, lines, i));
(*env)->ReleaseStringUTFChars(env, line, c_lines[i]);
}
if (code != TSDB_CODE_SUCCESS) {
jniError("jobj:%p, conn:%p, code:%s", jobj, taos, tstrerror(code));
return JNI_TDENGINE_ERROR;
}
return code;
}
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "tscLog.h" #include "tscLog.h"
#include "taos.h" #include "taos.h"
typedef struct { typedef struct {
char sTableName[TSDB_TABLE_NAME_LEN]; char sTableName[TSDB_TABLE_NAME_LEN];
SHashObj* tagHash; SHashObj* tagHash;
...@@ -33,7 +34,7 @@ typedef struct { ...@@ -33,7 +34,7 @@ typedef struct {
char* value; char* value;
//=================================== //===================================
SSchema* schema; size_t fieldSchemaIdx;
} TAOS_SML_KV; } TAOS_SML_KV;
typedef struct { typedef struct {
...@@ -48,9 +49,17 @@ typedef struct { ...@@ -48,9 +49,17 @@ typedef struct {
int fieldNum; int fieldNum;
//================================ //================================
SSmlSTableSchema* schema; size_t schemaIdx;
} TAOS_SML_DATA_POINT; } TAOS_SML_DATA_POINT;
typedef enum {
SML_TIME_STAMP_NOW,
SML_TIME_STAMP_SECONDS,
SML_TIME_STAMP_MILLI_SECONDS,
SML_TIME_STAMP_MICRO_SECONDS,
SML_TIME_STAMP_NANO_SECONDS
} SMLTimeStampType;
//================================================================================================= //=================================================================================================
int compareSmlColKv(const void* p1, const void* p2) { int compareSmlColKv(const void* p1, const void* p2) {
...@@ -117,10 +126,12 @@ static int32_t getFieldBytesFromSmlKv(TAOS_SML_KV* kv, int32_t* bytes) { ...@@ -117,10 +126,12 @@ static int32_t getFieldBytesFromSmlKv(TAOS_SML_KV* kv, int32_t* bytes) {
static int32_t buildSmlKvSchema(TAOS_SML_KV* smlKv, SHashObj* hash, SArray* array) { static int32_t buildSmlKvSchema(TAOS_SML_KV* smlKv, SHashObj* hash, SArray* array) {
SSchema* pField = NULL; SSchema* pField = NULL;
SSchema** ppField = taosHashGet(hash, smlKv->key, strlen(smlKv->key)); size_t* pFieldIdx = taosHashGet(hash, smlKv->key, strlen(smlKv->key));
size_t fieldIdx = -1;
int32_t code = 0; int32_t code = 0;
if (ppField) { if (pFieldIdx) {
pField = *ppField; fieldIdx = *pFieldIdx;
pField = taosArrayGet(array, fieldIdx);
if (pField->type != smlKv->type) { if (pField->type != smlKv->type) {
tscError("type mismatch. key %s, type %d. type before %d", smlKv->key, smlKv->type, pField->type); tscError("type mismatch. key %s, type %d. type before %d", smlKv->key, smlKv->type, pField->type);
...@@ -149,10 +160,11 @@ static int32_t buildSmlKvSchema(TAOS_SML_KV* smlKv, SHashObj* hash, SArray* arra ...@@ -149,10 +160,11 @@ static int32_t buildSmlKvSchema(TAOS_SML_KV* smlKv, SHashObj* hash, SArray* arra
field.bytes = bytes; field.bytes = bytes;
pField = taosArrayPush(array, &field); pField = taosArrayPush(array, &field);
taosHashPut(hash, field.name, tagKeyLen, &pField, POINTER_BYTES); fieldIdx = taosArrayGetSize(array) - 1;
taosHashPut(hash, field.name, tagKeyLen, &fieldIdx, sizeof(fieldIdx));
} }
smlKv->schema = pField; smlKv->fieldSchemaIdx = fieldIdx;
return 0; return 0;
} }
...@@ -165,10 +177,12 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint, ...@@ -165,10 +177,12 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint,
for (int i = 0; i < numPoint; ++i) { for (int i = 0; i < numPoint; ++i) {
TAOS_SML_DATA_POINT* point = &points[i]; TAOS_SML_DATA_POINT* point = &points[i];
size_t stableNameLen = strlen(point->stableName); size_t stableNameLen = strlen(point->stableName);
SSmlSTableSchema** ppStableSchema = taosHashGet(sname2shema, point->stableName, stableNameLen); size_t* pStableIdx = taosHashGet(sname2shema, point->stableName, stableNameLen);
SSmlSTableSchema* pStableSchema = NULL; SSmlSTableSchema* pStableSchema = NULL;
if (ppStableSchema) { size_t stableIdx = -1;
pStableSchema= *ppStableSchema; if (pStableIdx) {
pStableSchema= taosArrayGet(stableSchemas, *pStableIdx);
stableIdx = *pStableIdx;
} else { } else {
SSmlSTableSchema schema; SSmlSTableSchema schema;
strncpy(schema.sTableName, point->stableName, stableNameLen); strncpy(schema.sTableName, point->stableName, stableNameLen);
...@@ -179,7 +193,8 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint, ...@@ -179,7 +193,8 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint,
schema.fieldHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false); schema.fieldHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, false);
pStableSchema = taosArrayPush(stableSchemas, &schema); pStableSchema = taosArrayPush(stableSchemas, &schema);
taosHashPut(sname2shema, schema.sTableName, stableNameLen, &pStableSchema, POINTER_BYTES); stableIdx = taosArrayGetSize(stableSchemas) - 1;
taosHashPut(sname2shema, schema.sTableName, stableNameLen, &stableIdx, sizeof(size_t));
} }
for (int j = 0; j < point->tagNum; ++j) { for (int j = 0; j < point->tagNum; ++j) {
...@@ -200,7 +215,7 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint, ...@@ -200,7 +215,7 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint,
} }
} }
point->schema = pStableSchema; point->schemaIdx = stableIdx;
} }
size_t numStables = taosArrayGetSize(stableSchemas); size_t numStables = taosArrayGetSize(stableSchemas);
...@@ -221,11 +236,12 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint, ...@@ -221,11 +236,12 @@ static int32_t buildDataPointSchemas(TAOS_SML_DATA_POINT* points, int numPoint,
return 0; return 0;
} }
static int32_t generateSchemaAction(SSchema* pointColField, SHashObj* dbAttrHash, bool isTag, char sTableName[], static int32_t generateSchemaAction(SSchema* pointColField, SHashObj* dbAttrHash, SArray* dbAttrArray, bool isTag, char sTableName[],
SSchemaAction* action, bool* actionNeeded) { SSchemaAction* action, bool* actionNeeded) {
SSchema** ppDbAttr = taosHashGet(dbAttrHash, pointColField->name, strlen(pointColField->name)); size_t* pDbIndex = taosHashGet(dbAttrHash, pointColField->name, strlen(pointColField->name));
if (ppDbAttr) { if (pDbIndex) {
SSchema* dbAttr = *ppDbAttr; SSchema* dbAttr = taosArrayGet(dbAttrArray, *pDbIndex);
assert(strcasecmp(dbAttr->name, pointColField->name) == 0);
if (pointColField->type != dbAttr->type) { if (pointColField->type != dbAttr->type) {
tscError("point type and db type mismatch. key: %s. point type: %d, db type: %d", pointColField->name, tscError("point type and db type mismatch. key: %s. point type: %d, db type: %d", pointColField->name,
pointColField->type, dbAttr->type); pointColField->type, dbAttr->type);
...@@ -437,8 +453,9 @@ int32_t loadTableMeta(TAOS* taos, char* tableName, SSmlSTableSchema* schema) { ...@@ -437,8 +453,9 @@ int32_t loadTableMeta(TAOS* taos, char* tableName, SSmlSTableSchema* schema) {
tstrncpy(field.name, tableMeta->schema[i].name, strlen(tableMeta->schema[i].name)+1); tstrncpy(field.name, tableMeta->schema[i].name, strlen(tableMeta->schema[i].name)+1);
field.type = tableMeta->schema[i].type; field.type = tableMeta->schema[i].type;
field.bytes = tableMeta->schema[i].bytes; field.bytes = tableMeta->schema[i].bytes;
SSchema* pField = taosArrayPush(schema->fields, &field); taosArrayPush(schema->fields, &field);
taosHashPut(schema->fieldHash, field.name, strlen(field.name), &pField, POINTER_BYTES); size_t fieldIndex = taosArrayGetSize(schema->fields) - 1;
taosHashPut(schema->fieldHash, field.name, strlen(field.name), &fieldIndex, sizeof(fieldIndex));
} }
for (int i=0; i<tableMeta->tableInfo.numOfTags; ++i) { for (int i=0; i<tableMeta->tableInfo.numOfTags; ++i) {
...@@ -447,8 +464,9 @@ int32_t loadTableMeta(TAOS* taos, char* tableName, SSmlSTableSchema* schema) { ...@@ -447,8 +464,9 @@ int32_t loadTableMeta(TAOS* taos, char* tableName, SSmlSTableSchema* schema) {
tstrncpy(field.name, tableMeta->schema[j].name, strlen(tableMeta->schema[j].name)+1); tstrncpy(field.name, tableMeta->schema[j].name, strlen(tableMeta->schema[j].name)+1);
field.type = tableMeta->schema[j].type; field.type = tableMeta->schema[j].type;
field.bytes = tableMeta->schema[j].bytes; field.bytes = tableMeta->schema[j].bytes;
SSchema* pField = taosArrayPush(schema->tags, &field); taosArrayPush(schema->tags, &field);
taosHashPut(schema->tagHash, field.name, strlen(field.name), &pField, POINTER_BYTES); size_t tagIndex = taosArrayGetSize(schema->tags) - 1;
taosHashPut(schema->tagHash, field.name, strlen(field.name), &tagIndex, sizeof(tagIndex));
} }
tscDebug("load table meta succeed. %s, columns number: %d, tag number: %d, precision: %d", tscDebug("load table meta succeed. %s, columns number: %d, tag number: %d, precision: %d",
tableName, tableMeta->tableInfo.numOfColumns, tableMeta->tableInfo.numOfTags, schema->precision); tableName, tableMeta->tableInfo.numOfColumns, tableMeta->tableInfo.numOfTags, schema->precision);
...@@ -476,6 +494,7 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) { ...@@ -476,6 +494,7 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) {
code = loadTableMeta(taos, pointSchema->sTableName, &dbSchema); code = loadTableMeta(taos, pointSchema->sTableName, &dbSchema);
if (code != 0) { if (code != 0) {
tscError("reconcile point schema failed. can not create %s", pointSchema->sTableName); tscError("reconcile point schema failed. can not create %s", pointSchema->sTableName);
return code;
} else { } else {
pointSchema->precision = dbSchema.precision; pointSchema->precision = dbSchema.precision;
destroySmlSTableSchema(&dbSchema); destroySmlSTableSchema(&dbSchema);
...@@ -491,7 +510,7 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) { ...@@ -491,7 +510,7 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) {
SSchema* pointTag = taosArrayGet(pointSchema->tags, j); SSchema* pointTag = taosArrayGet(pointSchema->tags, j);
SSchemaAction schemaAction = {0}; SSchemaAction schemaAction = {0};
bool actionNeeded = false; bool actionNeeded = false;
generateSchemaAction(pointTag, dbTagHash, true, pointSchema->sTableName, &schemaAction, &actionNeeded); generateSchemaAction(pointTag, dbTagHash, dbSchema.tags, true, pointSchema->sTableName, &schemaAction, &actionNeeded);
if (actionNeeded) { if (actionNeeded) {
applySchemaAction(taos, &schemaAction); applySchemaAction(taos, &schemaAction);
} }
...@@ -505,7 +524,7 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) { ...@@ -505,7 +524,7 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) {
SSchema* pointCol = taosArrayGet(pointSchema->fields, j); SSchema* pointCol = taosArrayGet(pointSchema->fields, j);
SSchemaAction schemaAction = {0}; SSchemaAction schemaAction = {0};
bool actionNeeded = false; bool actionNeeded = false;
generateSchemaAction(pointCol, dbFieldHash, false, pointSchema->sTableName, &schemaAction, &actionNeeded); generateSchemaAction(pointCol, dbFieldHash, dbSchema.fields,false, pointSchema->sTableName, &schemaAction, &actionNeeded);
if (actionNeeded) { if (actionNeeded) {
applySchemaAction(taos, &schemaAction); applySchemaAction(taos, &schemaAction);
} }
...@@ -522,7 +541,8 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) { ...@@ -522,7 +541,8 @@ static int32_t reconcileDBSchemas(TAOS* taos, SArray* stableSchemas) {
return 0; return 0;
} }
static int32_t getChildTableName(TAOS_SML_DATA_POINT* point, char* tableName, int* tableNameLen) { static int32_t getSmlMd5ChildTableName(TAOS_SML_DATA_POINT* point, char* tableName, int* tableNameLen) {
tscDebug("taos_sml_insert get child table name through md5");
qsort(point->tags, point->tagNum, sizeof(TAOS_SML_KV), compareSmlColKv); qsort(point->tags, point->tagNum, sizeof(TAOS_SML_KV), compareSmlColKv);
SStringBuilder sb; memset(&sb, 0, sizeof(sb)); SStringBuilder sb; memset(&sb, 0, sizeof(sb));
...@@ -592,8 +612,12 @@ static int32_t creatChildTableIfNotExists(TAOS* taos, const char* cTableName, co ...@@ -592,8 +612,12 @@ static int32_t creatChildTableIfNotExists(TAOS* taos, const char* cTableName, co
return code; return code;
} }
taos_stmt_close(stmt); code = taos_stmt_close(stmt);
return 0; if (code != 0) {
tscError("%s", taos_stmt_errstr(stmt));
return code;
}
return code;
} }
static int32_t insertChildTableBatch(TAOS* taos, char* cTableName, SArray* colsSchema, SArray* rowsBind) { static int32_t insertChildTableBatch(TAOS* taos, char* cTableName, SArray* colsSchema, SArray* rowsBind) {
...@@ -619,7 +643,7 @@ static int32_t insertChildTableBatch(TAOS* taos, char* cTableName, SArray* cols ...@@ -619,7 +643,7 @@ static int32_t insertChildTableBatch(TAOS* taos, char* cTableName, SArray* cols
int32_t try = 0; int32_t try = 0;
TAOS_STMT* stmt = taos_stmt_init(taos); TAOS_STMT* stmt = taos_stmt_init(taos);
code = taos_stmt_prepare(stmt, sql, (unsigned long)strlen(sql)); code = taos_stmt_prepare(stmt, sql, (unsigned long)strlen(sql));
if (code != 0) { if (code != 0) {
tscError("%s", taos_stmt_errstr(stmt)); tscError("%s", taos_stmt_errstr(stmt));
...@@ -665,23 +689,26 @@ static int32_t insertChildTableBatch(TAOS* taos, char* cTableName, SArray* cols ...@@ -665,23 +689,26 @@ static int32_t insertChildTableBatch(TAOS* taos, char* cTableName, SArray* cols
return code; return code;
} }
static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int numPoints, SHashObj* cname2points) { static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int numPoints,
SHashObj* cname2points, SArray* stableSchemas) {
for (int32_t i = 0; i < numPoints; ++i) { for (int32_t i = 0; i < numPoints; ++i) {
TAOS_SML_DATA_POINT * point = points + i; TAOS_SML_DATA_POINT * point = points + i;
if (!point->childTableName) { if (!point->childTableName) {
char childTableName[TSDB_TABLE_NAME_LEN]; char childTableName[TSDB_TABLE_NAME_LEN];
int32_t tableNameLen = TSDB_TABLE_NAME_LEN; int32_t tableNameLen = TSDB_TABLE_NAME_LEN;
getChildTableName(point, childTableName, &tableNameLen); getSmlMd5ChildTableName(point, childTableName, &tableNameLen);
point->childTableName = calloc(1, tableNameLen+1); point->childTableName = calloc(1, tableNameLen+1);
strncpy(point->childTableName, childTableName, tableNameLen); strncpy(point->childTableName, childTableName, tableNameLen);
point->childTableName[tableNameLen] = '\0'; point->childTableName[tableNameLen] = '\0';
} }
SSmlSTableSchema* stableSchema = taosArrayGet(stableSchemas, point->schemaIdx);
for (int j = 0; j < point->tagNum; ++j) { for (int j = 0; j < point->tagNum; ++j) {
TAOS_SML_KV* kv = point->tags + j; TAOS_SML_KV* kv = point->tags + j;
if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) { if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) {
int64_t ts = *(int64_t*)(kv->value); int64_t ts = *(int64_t*)(kv->value);
ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, point->schema->precision); ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, stableSchema->precision);
*(int64_t*)(kv->value) = ts; *(int64_t*)(kv->value) = ts;
} }
} }
...@@ -690,7 +717,7 @@ static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int nu ...@@ -690,7 +717,7 @@ static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int nu
TAOS_SML_KV* kv = point->fields + j; TAOS_SML_KV* kv = point->fields + j;
if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) { if (kv->type == TSDB_DATA_TYPE_TIMESTAMP) {
int64_t ts = *(int64_t*)(kv->value); int64_t ts = *(int64_t*)(kv->value);
ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, point->schema->precision); ts = convertTimePrecision(ts, TSDB_TIME_PRECISION_NANO, stableSchema->precision);
*(int64_t*)(kv->value) = ts; *(int64_t*)(kv->value) = ts;
} }
} }
...@@ -709,10 +736,12 @@ static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int nu ...@@ -709,10 +736,12 @@ static int32_t arrangePointsByChildTableName(TAOS_SML_DATA_POINT* points, int nu
return 0; return 0;
} }
static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t numPoints) { static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t numPoints, SArray* stableSchemas) {
int32_t code = TSDB_CODE_SUCCESS;
SHashObj* cname2points = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), SHashObj* cname2points = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY),
true, false); true, false);
arrangePointsByChildTableName(points, numPoints, cname2points); arrangePointsByChildTableName(points, numPoints, cname2points, stableSchemas);
int isNullColBind = TSDB_TRUE; int isNullColBind = TSDB_TRUE;
SArray** pCTablePoints = taosHashIterate(cname2points, NULL); SArray** pCTablePoints = taosHashIterate(cname2points, NULL);
...@@ -720,8 +749,9 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num ...@@ -720,8 +749,9 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num
SArray* cTablePoints = *pCTablePoints; SArray* cTablePoints = *pCTablePoints;
TAOS_SML_DATA_POINT * point = taosArrayGetP(cTablePoints, 0); TAOS_SML_DATA_POINT * point = taosArrayGetP(cTablePoints, 0);
size_t numTags = taosArrayGetSize(point->schema->tags); SSmlSTableSchema* sTableSchema = taosArrayGet(stableSchemas, point->schemaIdx);
size_t numCols = taosArrayGetSize(point->schema->fields); size_t numTags = taosArrayGetSize(sTableSchema->tags);
size_t numCols = taosArrayGetSize(sTableSchema->fields);
SArray* tagBinds = taosArrayInit(numTags, sizeof(TAOS_BIND)); SArray* tagBinds = taosArrayInit(numTags, sizeof(TAOS_BIND));
taosArraySetSize(tagBinds, numTags); taosArraySetSize(tagBinds, numTags);
...@@ -731,8 +761,7 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num ...@@ -731,8 +761,7 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num
} }
for (int j = 0; j < point->tagNum; ++j) { for (int j = 0; j < point->tagNum; ++j) {
TAOS_SML_KV* kv = point->tags + j; TAOS_SML_KV* kv = point->tags + j;
size_t idx = TARRAY_ELEM_IDX(point->schema->tags, kv->schema); TAOS_BIND* bind = taosArrayGet(tagBinds, kv->fieldSchemaIdx);
TAOS_BIND* bind = taosArrayGet(tagBinds, idx);
bind->buffer_type = kv->type; bind->buffer_type = kv->type;
bind->length = malloc(sizeof(uintptr_t*)); bind->length = malloc(sizeof(uintptr_t*));
*bind->length = kv->length; *bind->length = kv->length;
...@@ -747,14 +776,17 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num ...@@ -747,14 +776,17 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num
point = taosArrayGetP(cTablePoints, i); point = taosArrayGetP(cTablePoints, i);
TAOS_BIND* colBinds = calloc(numCols, sizeof(TAOS_BIND)); TAOS_BIND* colBinds = calloc(numCols, sizeof(TAOS_BIND));
if (colBinds == NULL) {
tscError("taos_sml_insert insert points, failed to allocated memory for TAOS_BIND, "
"num of rows: %zu, num of cols: %zu", rows, numCols);
}
for (int j = 0; j < numCols; ++j) { for (int j = 0; j < numCols; ++j) {
TAOS_BIND* bind = colBinds + j; TAOS_BIND* bind = colBinds + j;
bind->is_null = &isNullColBind; bind->is_null = &isNullColBind;
} }
for (int j = 0; j < point->fieldNum; ++j) { for (int j = 0; j < point->fieldNum; ++j) {
TAOS_SML_KV* kv = point->fields + j; TAOS_SML_KV* kv = point->fields + j;
size_t idx = TARRAY_ELEM_IDX(point->schema->fields, kv->schema); TAOS_BIND* bind = colBinds + kv->fieldSchemaIdx;
TAOS_BIND* bind = colBinds + idx;
bind->buffer_type = kv->type; bind->buffer_type = kv->type;
bind->length = malloc(sizeof(uintptr_t*)); bind->length = malloc(sizeof(uintptr_t*));
*bind->length = kv->length; *bind->length = kv->length;
...@@ -764,14 +796,21 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num ...@@ -764,14 +796,21 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num
taosArrayPush(rowsBind, &colBinds); taosArrayPush(rowsBind, &colBinds);
} }
creatChildTableIfNotExists(taos, point->childTableName, point->stableName, point->schema->tags, tagBinds); code = creatChildTableIfNotExists(taos, point->childTableName, point->stableName, sTableSchema->tags, tagBinds);
if (code == 0) {
code = insertChildTableBatch(taos, point->childTableName, sTableSchema->fields, rowsBind);
if (code != 0) {
tscError("insert into child table %s failed. error %s", point->childTableName, tstrerror(code));
}
} else {
tscError("Create Child Table %s failed, error %s", point->childTableName, tstrerror(code));
}
for (int i = 0; i < taosArrayGetSize(tagBinds); ++i) { for (int i = 0; i < taosArrayGetSize(tagBinds); ++i) {
TAOS_BIND* bind = taosArrayGet(tagBinds, i); TAOS_BIND* bind = taosArrayGet(tagBinds, i);
free(bind->length); free(bind->length);
} }
taosArrayDestroy(tagBinds); taosArrayDestroy(tagBinds);
insertChildTableBatch(taos, point->childTableName, point->schema->fields, rowsBind);
for (int i = 0; i < rows; ++i) { for (int i = 0; i < rows; ++i) {
TAOS_BIND* colBinds = taosArrayGetP(rowsBind, i); TAOS_BIND* colBinds = taosArrayGetP(rowsBind, i);
for (int j = 0; j < numCols; ++j) { for (int j = 0; j < numCols; ++j) {
...@@ -782,12 +821,14 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num ...@@ -782,12 +821,14 @@ static int32_t insertPoints(TAOS* taos, TAOS_SML_DATA_POINT* points, int32_t num
} }
taosArrayDestroy(rowsBind); taosArrayDestroy(rowsBind);
taosArrayDestroy(cTablePoints); taosArrayDestroy(cTablePoints);
if (code != 0) {
break;
}
pCTablePoints = taosHashIterate(cname2points, pCTablePoints); pCTablePoints = taosHashIterate(cname2points, pCTablePoints);
} }
taosHashCleanup(cname2points); taosHashCleanup(cname2points);
return 0; return code;
} }
int taos_sml_insert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint) { int taos_sml_insert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint) {
...@@ -808,7 +849,7 @@ int taos_sml_insert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint) { ...@@ -808,7 +849,7 @@ int taos_sml_insert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint) {
goto clean_up; goto clean_up;
} }
code = insertPoints(taos, points, numPoint); code = insertPoints(taos, points, numPoint, stableSchemas);
if (code != 0) { if (code != 0) {
tscError("error insert points : %s", tstrerror(code)); tscError("error insert points : %s", tstrerror(code));
} }
...@@ -825,305 +866,886 @@ clean_up: ...@@ -825,305 +866,886 @@ clean_up:
//========================================================================= //=========================================================================
typedef enum { /* Field Escape charaters
LP_ITEM_TAG, 1: measurement Comma,Space
LP_ITEM_FIELD 2: tag_key, tag_value, field_key Comma,Equal Sign,Space
} LPItemKind; 3: field_value Double quote,Backslash
*/
static void escapeSpecialCharacter(uint8_t field, const char **pos) {
const char *cur = *pos;
if (*cur != '\\') {
return;
}
switch (field) {
case 1:
switch (*(cur + 1)) {
case ',':
case ' ':
cur++;
break;
default:
break;
}
break;
case 2:
switch (*(cur + 1)) {
case ',':
case ' ':
case '=':
cur++;
break;
default:
break;
}
break;
case 3:
switch (*(cur + 1)) {
case '"':
case '\\':
cur++;
break;
default:
break;
}
break;
default:
break;
}
*pos = cur;
}
typedef struct { static bool isValidInteger(char *str) {
SStrToken keyToken; char *c = str;
SStrToken valueToken; if (*c != '+' && *c != '-' && !isdigit(*c)) {
return false;
}
c++;
while (*c != '\0') {
if (!isdigit(*c)) {
return false;
}
c++;
}
return true;
}
char key[TSDB_COL_NAME_LEN]; static bool isValidFloat(char *str) {
int8_t type; char *c = str;
int16_t length; uint8_t has_dot, has_exp, has_sign;
has_dot = 0;
has_exp = 0;
has_sign = 0;
char* value; if (*c != '+' && *c != '-' && *c != '.' && !isdigit(*c)) {
}SLPItem; return false;
}
if (*c == '.' && isdigit(*(c + 1))) {
has_dot = 1;
}
c++;
while (*c != '\0') {
if (!isdigit(*c)) {
switch (*c) {
case '.': {
if (!has_dot && !has_exp && isdigit(*(c + 1))) {
has_dot = 1;
} else {
return false;
}
break;
}
case 'e':
case 'E': {
if (!has_exp && isdigit(*(c - 1)) &&
(isdigit(*(c + 1)) ||
*(c + 1) == '+' ||
*(c + 1) == '-')) {
has_exp = 1;
} else {
return false;
}
break;
}
case '+':
case '-': {
if (!has_sign && has_exp && isdigit(*(c + 1))) {
has_sign = 1;
} else {
return false;
}
break;
}
default: {
return false;
}
}
}
c++;
} //while
return true;
}
typedef struct { static bool isTinyInt(char *pVal, uint16_t len) {
SStrToken measToken; if (len <= 2) {
SStrToken tsToken; return false;
}
if (!strcmp(&pVal[len - 2], "i8")) {
//printf("Type is int8(%s)\n", pVal);
return true;
}
return false;
}
char sTableName[TSDB_TABLE_NAME_LEN]; static bool isTinyUint(char *pVal, uint16_t len) {
SArray* tags; if (len <= 2) {
SArray* fields; return false;
int64_t ts; }
if (pVal[0] == '-') {
return false;
}
if (!strcmp(&pVal[len - 2], "u8")) {
//printf("Type is uint8(%s)\n", pVal);
return true;
}
return false;
}
} SLPPoint; static bool isSmallInt(char *pVal, uint16_t len) {
if (len <= 3) {
return false;
}
if (!strcmp(&pVal[len - 3], "i16")) {
//printf("Type is int16(%s)\n", pVal);
return true;
}
return false;
}
typedef enum { static bool isSmallUint(char *pVal, uint16_t len) {
LP_MEASUREMENT, if (len <= 3) {
LP_TAG_KEY, return false;
LP_TAG_VALUE, }
LP_FIELD_KEY, if (pVal[0] == '-') {
LP_FIELD_VALUE return false;
} LPPart; }
if (strcmp(&pVal[len - 3], "u16") == 0) {
//printf("Type is uint16(%s)\n", pVal);
return true;
}
return false;
}
int32_t scanToCommaOrSpace(SStrToken s, int32_t start, int32_t* index, LPPart part) { static bool isInt(char *pVal, uint16_t len) {
for (int32_t i = start; i < s.n; ++i) { if (len <= 3) {
if (s.z[i] == ',' || s.z[i] == ' ') { return false;
*index = i; }
return 0; if (strcmp(&pVal[len - 3], "i32") == 0) {
} //printf("Type is int32(%s)\n", pVal);
return true;
} }
return -1; return false;
} }
int32_t scanToEqual(SStrToken s, int32_t start, int32_t* index) { static bool isUint(char *pVal, uint16_t len) {
for (int32_t i = start; i < s.n; ++i) { if (len <= 3) {
if (s.z[i] == '=') { return false;
*index = i; }
return 0; if (pVal[0] == '-') {
} return false;
} }
return -1; if (strcmp(&pVal[len - 3], "u32") == 0) {
//printf("Type is uint32(%s)\n", pVal);
return true;
}
return false;
} }
int32_t setPointMeasurement(SLPPoint* point, SStrToken token) { static bool isBigInt(char *pVal, uint16_t len) {
point->measToken = token; if (len <= 3) {
if (point->measToken.n < TSDB_TABLE_NAME_LEN) { return false;
strncpy(point->sTableName, point->measToken.z, point->measToken.n);
point->sTableName[point->measToken.n] = '\0';
} }
return 0; if (strcmp(&pVal[len - 3], "i64") == 0) {
//printf("Type is int64(%s)\n", pVal);
return true;
}
return false;
} }
int32_t setItemKey(SLPItem* item, SStrToken key, LPPart part) { static bool isBigUint(char *pVal, uint16_t len) {
item->keyToken = key; if (len <= 3) {
if (item->keyToken.n < TSDB_COL_NAME_LEN) { return false;
strncpy(item->key, item->keyToken.z, item->keyToken.n);
item->key[item->keyToken.n] = '\0';
} }
return 0; if (pVal[0] == '-') {
return false;
}
if (strcmp(&pVal[len - 3], "u64") == 0) {
//printf("Type is uint64(%s)\n", pVal);
return true;
}
return false;
} }
int32_t setItemValue(SLPItem* item, SStrToken value, LPPart part) { static bool isFloat(char *pVal, uint16_t len) {
item->valueToken = value; if (len <= 3) {
return 0; return false;
}
if (strcmp(&pVal[len - 3], "f32") == 0) {
//printf("Type is float(%s)\n", pVal);
return true;
}
return false;
} }
int32_t parseItemValue(SLPItem* item, LPItemKind kind) { static bool isDouble(char *pVal, uint16_t len) {
char* sv = item->valueToken.z; if (len <= 3) {
char* last = item->valueToken.z + item->valueToken.n - 1; return false;
if (isdigit(sv[0]) || sv[0] == '-') {
if (*last == 'i') {
item->type = TSDB_DATA_TYPE_BIGINT;
item->length = (int16_t)tDataTypes[item->type].bytes;
item->value = malloc(item->length);
char* endptr = NULL;
*(int64_t*)(item->value) = strtoll(sv, &endptr, 10);
} else if (*last == 'u') {
item->type = TSDB_DATA_TYPE_UBIGINT;
item->length = (int16_t)tDataTypes[item->type].bytes;
item->value = malloc(item->length);
char* endptr = NULL;
*(uint64_t*)(item->value) = (uint64_t)strtoull(sv, &endptr, 10);
} else if (*last == 'b') {
item->type = TSDB_DATA_TYPE_TINYINT;
item->length = (int16_t)tDataTypes[item->type].bytes;
item->value = malloc(item->length);
char* endptr = NULL;
*(int8_t*)(item->value) = (int8_t)strtoll(sv, &endptr, 10);
} else if (*last == 's') {
item->type = TSDB_DATA_TYPE_SMALLINT;
item->length = (int16_t)tDataTypes[item->type].bytes;
item->value = malloc(item->length);
char* endptr = NULL;
*(int16_t*)(item->value) = (int16_t)strtoll(sv, &endptr, 10);
} else if (*last == 'w') {
item->type = TSDB_DATA_TYPE_INT;
item->length = (int16_t)tDataTypes[item->type].bytes;
item->value = malloc(item->length);
char* endptr = NULL;
*(int32_t*)(item->value) = (int32_t)strtoll(sv, &endptr, 10);
} else if (*last == 'f') {
item->type = TSDB_DATA_TYPE_FLOAT;
item->length = (int16_t)tDataTypes[item->type].bytes;
item->value = malloc(item->length);
char* endptr = NULL;
*(float*)(item->value) = (float)strtold(sv, &endptr);
} else {
item->type = TSDB_DATA_TYPE_DOUBLE;
item->length = (int16_t)tDataTypes[item->type].bytes;
item->value = malloc(item->length);
char* endptr = NULL;
*(double*)(item->value) = strtold(sv, &endptr);
}
} else if ((sv[0] == 'L' && sv[1] =='"') || sv[0] == '"' ) {
if (sv[0] == 'L') {
item->type = TSDB_DATA_TYPE_NCHAR;
uint32_t bytes = item->valueToken.n - 3;
item->length = bytes;
item->value = malloc(bytes);
memcpy(item->value, sv+2, bytes);
} else if (sv[0]=='"'){
item->type = TSDB_DATA_TYPE_BINARY;
uint32_t bytes = item->valueToken.n - 2;
item->length = bytes;
item->value = malloc(bytes);
memcpy(item->value, sv+1, bytes);
}
} else if (sv[0] == 't' || sv[0] == 'f' || sv[0]=='T' || sv[0] == 'F') {
item->type = TSDB_DATA_TYPE_BOOL;
item->length = tDataTypes[item->type].bytes;
item->value = malloc(tDataTypes[item->type].bytes);
*(uint8_t*)(item->value) = tolower(sv[0])=='t' ? TSDB_TRUE : TSDB_FALSE;
} }
return 0; if (strcmp(&pVal[len - 3], "f64") == 0) {
//printf("Type is double(%s)\n", pVal);
return true;
}
return false;
} }
int32_t compareLPItemKey(const void* p1, const void* p2) { static bool isBool(char *pVal, uint16_t len, bool *bVal) {
const SLPItem* t1 = p1; if ((len == 1) &&
const SLPItem* t2 = p2; (pVal[len - 1] == 't' ||
uint32_t min = (t1->keyToken.n < t2->keyToken.n) ? t1->keyToken.n : t2->keyToken.n; pVal[len - 1] == 'T')) {
int res = strncmp(t1->keyToken.z, t2->keyToken.z, min); //printf("Type is bool(%c)\n", pVal[len - 1]);
if (res != 0) { *bVal = true;
return res; return true;
} else { }
return (int)(t1->keyToken.n) - (int)(t2->keyToken.n);
if ((len == 1) &&
(pVal[len - 1] == 'f' ||
pVal[len - 1] == 'F')) {
//printf("Type is bool(%c)\n", pVal[len - 1]);
*bVal = false;
return true;
}
if((len == 4) &&
(!strcmp(&pVal[len - 4], "true") ||
!strcmp(&pVal[len - 4], "True") ||
!strcmp(&pVal[len - 4], "TRUE"))) {
//printf("Type is bool(%s)\n", &pVal[len - 4]);
*bVal = true;
return true;
}
if((len == 5) &&
(!strcmp(&pVal[len - 5], "false") ||
!strcmp(&pVal[len - 5], "False") ||
!strcmp(&pVal[len - 5], "FALSE"))) {
//printf("Type is bool(%s)\n", &pVal[len - 5]);
*bVal = false;
return true;
} }
return false;
} }
int32_t setPointTimeStamp(SLPPoint* point, SStrToken tsToken) { static bool isBinary(char *pVal, uint16_t len) {
point->tsToken = tsToken; //binary: "abc"
return 0; if (len < 2) {
return false;
}
//binary
if (pVal[0] == '"' && pVal[len - 1] == '"') {
//printf("Type is binary(%s)\n", pVal);
return true;
}
return false;
}
static bool isNchar(char *pVal, uint16_t len) {
//nchar: L"abc"
if (len < 3) {
return false;
}
if (pVal[0] == 'L' && pVal[1] == '"' && pVal[len - 1] == '"') {
//printf("Type is nchar(%s)\n", pVal);
return true;
}
return false;
}
static bool isTimeStamp(char *pVal, uint16_t len, SMLTimeStampType *tsType) {
if (len == 0) {
return true;
}
if ((len == 1) && pVal[0] == '0') {
*tsType = SML_TIME_STAMP_NOW;
//printf("Type is timestamp(%s)\n", pVal);
return true;
}
if (len < 2) {
return false;
}
//No appendix use usec as default
if (isdigit(pVal[len - 1]) && isdigit(pVal[len - 2])) {
*tsType = SML_TIME_STAMP_MICRO_SECONDS;
//printf("Type is timestamp(%s)\n", pVal);
return true;
}
if (pVal[len - 1] == 's') {
switch (pVal[len - 2]) {
case 'm':
*tsType = SML_TIME_STAMP_MILLI_SECONDS;
break;
case 'u':
*tsType = SML_TIME_STAMP_MICRO_SECONDS;
break;
case 'n':
*tsType = SML_TIME_STAMP_NANO_SECONDS;
break;
default:
if (isdigit(pVal[len - 2])) {
*tsType = SML_TIME_STAMP_SECONDS;
break;
} else {
return false;
}
}
//printf("Type is timestamp(%s)\n", pVal);
return true;
}
return false;
}
//len does not include '\0' from value.
static bool convertSmlValueType(TAOS_SML_KV *pVal, char *value,
uint16_t len) {
if (len <= 0) {
return false;
}
//integer number
if (isTinyInt(value, len)) {
pVal->type = TSDB_DATA_TYPE_TINYINT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 2] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
int8_t val = (int8_t)strtoll(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isTinyUint(value, len)) {
pVal->type = TSDB_DATA_TYPE_UTINYINT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 2] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
uint8_t val = (uint8_t)strtoul(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isSmallInt(value, len)) {
pVal->type = TSDB_DATA_TYPE_SMALLINT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
int16_t val = (int16_t)strtoll(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isSmallUint(value, len)) {
pVal->type = TSDB_DATA_TYPE_USMALLINT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
uint16_t val = (uint16_t)strtoul(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
//memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isInt(value, len)) {
pVal->type = TSDB_DATA_TYPE_INT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
int32_t val = (int32_t)strtoll(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isUint(value, len)) {
pVal->type = TSDB_DATA_TYPE_UINT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
uint32_t val = (uint32_t)strtoul(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isBigInt(value, len)) {
pVal->type = TSDB_DATA_TYPE_BIGINT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
int64_t val = (int64_t)strtoll(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isBigUint(value, len)) {
pVal->type = TSDB_DATA_TYPE_UBIGINT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidInteger(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
uint64_t val = (uint64_t)strtoul(value, NULL, 10);
memcpy(pVal->value, &val, pVal->length);
return true;
}
//floating number
if (isFloat(value, len)) {
pVal->type = TSDB_DATA_TYPE_FLOAT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidFloat(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
float val = (float)strtold(value, NULL);
memcpy(pVal->value, &val, pVal->length);
return true;
}
if (isDouble(value, len)) {
pVal->type = TSDB_DATA_TYPE_DOUBLE;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
value[len - 3] = '\0';
if (!isValidFloat(value)) {
return false;
}
pVal->value = calloc(pVal->length, 1);
double val = (double)strtold(value, NULL);
memcpy(pVal->value, &val, pVal->length);
return true;
}
//binary
if (isBinary(value, len)) {
pVal->type = TSDB_DATA_TYPE_BINARY;
pVal->length = len - 2;
pVal->value = calloc(pVal->length, 1);
//copy after "
memcpy(pVal->value, value + 1, pVal->length);
return true;
}
//nchar
if (isNchar(value, len)) {
pVal->type = TSDB_DATA_TYPE_NCHAR;
pVal->length = len - 3;
pVal->value = calloc(pVal->length, 1);
//copy after L"
memcpy(pVal->value, value + 2, pVal->length);
return true;
}
//bool
bool bVal;
if (isBool(value, len, &bVal)) {
pVal->type = TSDB_DATA_TYPE_BOOL;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
pVal->value = calloc(pVal->length, 1);
memcpy(pVal->value, &bVal, pVal->length);
return true;
}
//Handle default(no appendix) as float
if (isValidInteger(value) || isValidFloat(value)) {
pVal->type = TSDB_DATA_TYPE_FLOAT;
pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
pVal->value = calloc(pVal->length, 1);
float val = (float)strtold(value, NULL);
memcpy(pVal->value, &val, pVal->length);
return true;
}
return false;
} }
int32_t parsePointTime(SLPPoint* point) { static int32_t getTimeStampValue(char *value, uint16_t len,
if (point->tsToken.n <= 0) { SMLTimeStampType type, int64_t *ts) {
point->ts = taosGetTimestampNs();
if (len >= 2) {
for (int i = 0; i < len - 2; ++i) {
if(!isdigit(value[i])) {
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
}
}
}
//No appendix or no timestamp given (len = 0)
if (len >= 1 && isdigit(value[len - 1]) && type != SML_TIME_STAMP_NOW) {
type = SML_TIME_STAMP_MICRO_SECONDS;
}
if (len != 0) {
*ts = (int64_t)strtoll(value, NULL, 10);
} else { } else {
char* endptr = NULL; type = SML_TIME_STAMP_NOW;
point->ts = strtoll(point->tsToken.z, &endptr, 10); }
char* last = point->tsToken.z + point->tsToken.n - 1; switch (type) {
if (*last == 's') { case SML_TIME_STAMP_NOW: {
point->ts *= (int64_t)1e9; *ts = taosGetTimestampNs();
} else if (*last == 'a') { break;
point->ts *= (int64_t)1e6; }
} else if (*last == 'u') { case SML_TIME_STAMP_SECONDS: {
point->ts *= (int64_t)1e3; *ts = (int64_t)(*ts * 1e9);
} else if (*last == 'b') { break;
point->ts *= 1; }
case SML_TIME_STAMP_MILLI_SECONDS: {
*ts = convertTimePrecision(*ts, TSDB_TIME_PRECISION_MILLI, TSDB_TIME_PRECISION_NANO);
break;
}
case SML_TIME_STAMP_MICRO_SECONDS: {
*ts = convertTimePrecision(*ts, TSDB_TIME_PRECISION_MICRO, TSDB_TIME_PRECISION_NANO);
break;
}
case SML_TIME_STAMP_NANO_SECONDS: {
*ts = *ts * 1;
break;
}
default: {
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} }
} }
return 0; return TSDB_CODE_SUCCESS;
} }
int32_t tscParseLine(SStrToken line, SLPPoint* point) { static int32_t convertSmlTimeStamp(TAOS_SML_KV *pVal, char *value,
int32_t pos = 0; uint16_t len) {
int32_t ret;
SMLTimeStampType type;
int64_t tsVal;
int32_t start = 0; if (!isTimeStamp(value, len, &type)) {
int32_t err = scanToCommaOrSpace(line, start, &pos, LP_MEASUREMENT); return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
if (err != 0) {
tscError("a");
return err;
} }
SStrToken measurement = {.z = line.z+start, .n = pos-start}; ret = getTimeStampValue(value, len, type, &tsVal);
setPointMeasurement(point, measurement); if (ret) {
point->tags = taosArrayInit(64, sizeof(SLPItem)); return ret;
start = pos; }
while (line.z[start] == ',') { tscDebug("Timestamp after conversion:%"PRId64, tsVal);
SLPItem item;
start++; pVal->type = TSDB_DATA_TYPE_TIMESTAMP;
err = scanToEqual(line, start, &pos); pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
if (err != 0) { pVal->value = calloc(pVal->length, 1);
tscError("b"); memcpy(pVal->value, &tsVal, pVal->length);
goto error; return TSDB_CODE_SUCCESS;
}
static int32_t parseSmlTimeStamp(TAOS_SML_KV **pTS, const char **index) {
const char *start, *cur;
int32_t ret = TSDB_CODE_SUCCESS;
int len = 0;
char key[] = "_ts";
char *value = NULL;
start = cur = *index;
*pTS = calloc(1, sizeof(TAOS_SML_KV));
while(*cur != '\0') {
cur++;
len++;
}
if (len > 0) {
value = calloc(len + 1, 1);
memcpy(value, start, len);
}
ret = convertSmlTimeStamp(*pTS, value, len);
if (ret) {
free(value);
free(*pTS);
return ret;
}
free(value);
(*pTS)->key = calloc(sizeof(key), 1);
memcpy((*pTS)->key, key, sizeof(key));
return ret;
}
static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index) {
const char *cur = *index;
char key[TSDB_COL_NAME_LEN];
uint16_t len = 0;
//key field cannot start with digit
if (isdigit(*cur)) {
tscError("Tag key cannnot start with digit\n");
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
}
while (*cur != '\0') {
if (len > TSDB_COL_NAME_LEN) {
tscDebug("Key field cannot exceeds 65 characters");
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
}
//unescaped '=' identifies a tag key
if (*cur == '=' && *(cur - 1) != '\\') {
break;
}
//Escape special character
if (*cur == '\\') {
escapeSpecialCharacter(2, &cur);
} }
key[len] = *cur;
cur++;
len++;
}
key[len] = '\0';
pKV->key = calloc(len + 1, 1);
memcpy(pKV->key, key, len + 1);
//tscDebug("Key:%s|len:%d", pKV->key, len);
*index = cur + 1;
return TSDB_CODE_SUCCESS;
}
SStrToken tagKey = {.z = line.z + start, .n = pos-start};
setItemKey(&item, tagKey, LP_TAG_KEY);
start = pos + 1; static bool parseSmlValue(TAOS_SML_KV *pKV, const char **index,
err = scanToCommaOrSpace(line, start, &pos, LP_TAG_VALUE); bool *is_last_kv) {
if (err != 0) { const char *start, *cur;
tscError("c"); char *value = NULL;
goto error; uint16_t len = 0;
start = cur = *index;
while (1) {
// unescaped ',' or ' ' or '\0' identifies a value
if ((*cur == ',' || *cur == ' ' || *cur == '\0') && *(cur - 1) != '\\') {
//unescaped ' ' or '\0' indicates end of value
*is_last_kv = (*cur == ' ' || *cur == '\0') ? true : false;
break;
} }
//Escape special character
if (*cur == '\\') {
escapeSpecialCharacter(2, &cur);
}
cur++;
len++;
}
SStrToken tagValue = {.z = line.z + start, .n = pos-start}; value = calloc(len + 1, 1);
setItemValue(&item, tagValue, LP_TAG_VALUE); memcpy(value, start, len);
value[len] = '\0';
if (!convertSmlValueType(pKV, value, len)) {
//free previous alocated key field
free(pKV->key);
free(value);
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
}
free(value);
parseItemValue(&item, LP_ITEM_TAG); *index = (*cur == '\0') ? cur : cur + 1;
taosArrayPush(point->tags, &item); return TSDB_CODE_SUCCESS;
}
start = pos; static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index,
uint8_t *has_tags) {
const char *cur = *index;
uint16_t len = 0;
pSml->stableName = calloc(TSDB_TABLE_NAME_LEN, 1);
if (isdigit(*cur)) {
tscError("Measurement field cannnot start with digit");
free(pSml->stableName);
pSml->stableName = NULL;
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} }
taosArraySort(point->tags, compareLPItemKey); while (*cur != '\0') {
if (len > TSDB_TABLE_NAME_LEN) {
tscError("Measurement field cannot exceeds 193 characters");
free(pSml->stableName);
pSml->stableName = NULL;
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
}
//first unescaped comma or space identifies measurement
//if space detected first, meaning no tag in the input
if (*cur == ',' && *(cur - 1) != '\\') {
*has_tags = 1;
break;
}
if (*cur == ' ' && *(cur - 1) != '\\') {
break;
}
//Comma, Space, Backslash needs to be escaped if any
if (*cur == '\\') {
escapeSpecialCharacter(1, &cur);
}
pSml->stableName[len] = *cur;
cur++;
len++;
}
pSml->stableName[len] = '\0';
*index = cur + 1;
tscDebug("Stable name in measurement:%s|len:%d", pSml->stableName, len);
point->fields = taosArrayInit(64, sizeof(SLPItem)); return TSDB_CODE_SUCCESS;
}
start++; static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs,
do { const char **index, bool isField, TAOS_SML_DATA_POINT* smlData) {
SLPItem item; const char *cur = *index;
int32_t ret = TSDB_CODE_SUCCESS;
TAOS_SML_KV *pkv;
bool is_last_kv = false;
int32_t capacity = 0;
if (isField) {
capacity = 64;
*pKVs = calloc(capacity, sizeof(TAOS_SML_KV));
// leave space for timestamp;
pkv = *pKVs;
pkv++;
} else {
capacity = 8;
*pKVs = calloc(capacity, sizeof(TAOS_SML_KV));
pkv = *pKVs;
}
err = scanToEqual(line, start, &pos); while (*cur != '\0') {
if (err != 0) { ret = parseSmlKey(pkv, &cur);
if (ret) {
tscError("Unable to parse key field");
goto error; goto error;
} }
SStrToken fieldKey = {.z = line.z + start, .n = pos- start}; ret = parseSmlValue(pkv, &cur, &is_last_kv);
setItemKey(&item, fieldKey, LP_FIELD_KEY); if (ret) {
tscError("Unable to parse value field");
start = pos + 1;
err = scanToCommaOrSpace(line, start, &pos, LP_FIELD_VALUE);
if (err != 0) {
goto error; goto error;
} }
SStrToken fieldValue = {.z = line.z + start, .n = pos - start}; if (!isField &&
setItemValue(&item, fieldValue, LP_TAG_VALUE); (strcasecmp(pkv->key, "ID") == 0) && pkv->type == TSDB_DATA_TYPE_BINARY) {
smlData->childTableName = malloc( pkv->length + 1);
parseItemValue(&item, LP_ITEM_FIELD); memcpy(smlData->childTableName, pkv->value, pkv->length);
taosArrayPush(point->fields, &item); smlData->childTableName[pkv->length] = '\0';
free(pkv->key);
start = pos + 1; free(pkv->value);
} while (line.z[pos] == ','); } else {
*num_kvs += 1;
}
if (is_last_kv) {
//tscDebug("last key-value field detected");
goto done;
}
taosArraySort(point->fields, compareLPItemKey); //reallocate addtional memory for more kvs
TAOS_SML_KV *more_kvs = NULL;
SStrToken tsToken = {.z = line.z+start, .n = line.n-start}; if (isField) {
setPointTimeStamp(point, tsToken); if ((*num_kvs + 2) > capacity) {
parsePointTime(point); capacity *= 3; capacity /= 2;
more_kvs = realloc(*pKVs, capacity * sizeof(TAOS_SML_KV));
} else {
more_kvs = *pKVs;
}
} else {
if ((*num_kvs + 1) > capacity) {
capacity *= 3; capacity /= 2;
more_kvs = realloc(*pKVs, capacity * sizeof(TAOS_SML_KV));
} else {
more_kvs = *pKVs;
}
}
if (!more_kvs) {
goto error;
}
*pKVs = more_kvs;
//move pKV points to next TAOS_SML_KV block
if (isField) {
pkv = *pKVs + *num_kvs + 1;
} else {
pkv = *pKVs + *num_kvs;
}
}
goto done; goto done;
error: error:
// free array return ret;
return err; done:
done: *index = cur;
return 0; return ret;
}
static void moveTimeStampToFirstKv(TAOS_SML_DATA_POINT** smlData, TAOS_SML_KV *ts) {
TAOS_SML_KV* tsField = (*smlData)->fields;
tsField->length = ts->length;
tsField->type = ts->type;
tsField->value = malloc(ts->length);
tsField->key = malloc(strlen(ts->key) + 1);
memcpy(tsField->key, ts->key, strlen(ts->key) + 1);
memcpy(tsField->value, ts->value, ts->length);
(*smlData)->fieldNum = (*smlData)->fieldNum + 1;
free(ts->key);
free(ts->value);
free(ts);
} }
int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData) {
const char* index = sql;
int32_t ret = TSDB_CODE_SUCCESS;
uint8_t has_tags = 0;
TAOS_SML_KV *timestamp = NULL;
int32_t tscParseLines(char* lines[], int numLines, SArray* points, SArray* failedLines) { ret = parseSmlMeasurement(smlData, &index, &has_tags);
for (int32_t i = 0; i < numLines; ++i) { if (ret) {
SStrToken tkLine = {.z = lines[i], .n = (uint32_t)strlen(lines[i])}; tscError("Unable to parse measurement");
SLPPoint point; return ret;
tscParseLine(tkLine, &point);
taosArrayPush(points, &point);
} }
return 0; tscDebug("Parse measurement finished, has_tags:%d", has_tags);
}
//Parse Tags
if (has_tags) {
ret = parseSmlKvPairs(&smlData->tags, &smlData->tagNum, &index, false, smlData);
if (ret) {
tscError("Unable to parse tag");
return ret;
}
}
tscDebug("Parse tags finished, num of tags:%d", smlData->tagNum);
void destroyLPPoint(void* p) { //Parse fields
SLPPoint* lpPoint = p; ret = parseSmlKvPairs(&smlData->fields, &smlData->fieldNum, &index, true, smlData);
for (int i=0; i<taosArrayGetSize(lpPoint->fields); ++i) { if (ret) {
SLPItem* item = taosArrayGet(lpPoint->fields, i); tscError("Unable to parse field");
free(item->value); return ret;
} }
taosArrayDestroy(lpPoint->fields); tscDebug("Parse fields finished, num of fields:%d", smlData->fieldNum);
for (int i=0; i<taosArrayGetSize(lpPoint->tags); ++i) { //Parse timestamp
SLPItem* item = taosArrayGet(lpPoint->tags, i); ret = parseSmlTimeStamp(&timestamp, &index);
free(item->value); if (ret) {
tscError("Unable to parse timestamp");
return ret;
} }
taosArrayDestroy(lpPoint->tags); moveTimeStampToFirstKv(&smlData, timestamp);
tscDebug("Parse timestamp finished");
return TSDB_CODE_SUCCESS;
} }
//=========================================================================
void destroySmlDataPoint(TAOS_SML_DATA_POINT* point) { void destroySmlDataPoint(TAOS_SML_DATA_POINT* point) {
for (int i=0; i<point->tagNum; ++i) { for (int i=0; i<point->tagNum; ++i) {
free((point->tags+i)->key); free((point->tags+i)->key);
...@@ -1139,76 +1761,67 @@ void destroySmlDataPoint(TAOS_SML_DATA_POINT* point) { ...@@ -1139,76 +1761,67 @@ void destroySmlDataPoint(TAOS_SML_DATA_POINT* point) {
free(point->childTableName); free(point->childTableName);
} }
int taos_insert_lines(TAOS* taos, char* lines[], int numLines) { int32_t tscParseLines(char* lines[], int numLines, SArray* points, SArray* failedLines) {
SArray* lpPoints = taosArrayInit(numLines, sizeof(SLPPoint)); for (int32_t i = 0; i < numLines; ++i) {
tscParseLines(lines, numLines, lpPoints, NULL); TAOS_SML_DATA_POINT point = {0};
int32_t code = tscParseLine(lines[i], &point);
size_t numPoints = taosArrayGetSize(lpPoints); if (code != TSDB_CODE_SUCCESS) {
TAOS_SML_DATA_POINT* points = calloc(numPoints, sizeof(TAOS_SML_DATA_POINT)); tscError("data point line parse failed. line %d : %s", i, lines[i]);
for (int i = 0; i < numPoints; ++i) { destroySmlDataPoint(&point);
SLPPoint* lpPoint = taosArrayGet(lpPoints, i); return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
TAOS_SML_DATA_POINT* point = points+i; } else {
point->stableName = calloc(1, strlen(lpPoint->sTableName)+1); tscDebug("data point line parse success. line %d", i);
strncpy(point->stableName, lpPoint->sTableName, strlen(lpPoint->sTableName)); }
point->stableName[strlen(lpPoint->sTableName)] = '\0';
size_t lpTagSize = taosArrayGetSize(lpPoint->tags);
point->tags = calloc(lpTagSize, sizeof(TAOS_SML_KV));
point->tagNum = (int)lpTagSize;
for (int j=0; j<lpTagSize; ++j) {
SLPItem* lpTag = taosArrayGet(lpPoint->tags, j);
TAOS_SML_KV* tagKv = point->tags + j;
size_t kenLen = strlen(lpTag->key); taosArrayPush(points, &point);
tagKv->key = calloc(1, kenLen+1); }
strncpy(tagKv->key, lpTag->key, kenLen); return 0;
tagKv->key[kenLen] = '\0'; }
tagKv->type = lpTag->type; int taos_insert_lines(TAOS* taos, char* lines[], int numLines) {
tagKv->length = lpTag->length; int32_t code = 0;
tagKv->value = malloc(tagKv->length);
memcpy(tagKv->value, lpTag->value, tagKv->length);
}
size_t lpFieldsSize = taosArrayGetSize(lpPoint->fields); if (numLines <= 0 || numLines > 65536) {
point->fields = calloc(lpFieldsSize + 1, sizeof(TAOS_SML_KV)); tscError("taos_insert_lines numLines should be between 1 and 65536. numLines: %d", numLines);
point->fieldNum = (int)(lpFieldsSize + 1); code = TSDB_CODE_TSC_APP_ERROR;
return code;
}
TAOS_SML_KV* tsField = point->fields + 0; for (int i = 0; i < numLines; ++i) {
char tsKey[256]; if (lines[i] == NULL) {
snprintf(tsKey, 256, "_%s_ts", point->stableName); tscError("taos_insert_lines line %d is NULL", i);
size_t tsKeyLen = strlen(tsKey); code = TSDB_CODE_TSC_APP_ERROR;
tsField->key = calloc(1, tsKeyLen+1); return code;
strncpy(tsField->key, tsKey, tsKeyLen); }
tsField->key[tsKeyLen] = '\0'; }
tsField->type = TSDB_DATA_TYPE_TIMESTAMP;
tsField->length = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
tsField->value = malloc(tsField->length);
memcpy(tsField->value, &(lpPoint->ts), tsField->length);
for (int j=0; j<lpFieldsSize; ++j) { SArray* lpPoints = taosArrayInit(numLines, sizeof(TAOS_SML_DATA_POINT));
SLPItem* lpField = taosArrayGet(lpPoint->fields, j); if (lpPoints == NULL) {
TAOS_SML_KV* fieldKv = point->fields + j + 1; tscError("taos_insert_lines failed to allocate memory");
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
size_t kenLen = strlen(lpField->key); tscDebug("taos_insert_lines begin inserting %d lines, first line: %s", numLines, lines[0]);
fieldKv->key = calloc(1, kenLen+1); code = tscParseLines(lines, numLines, lpPoints, NULL);
strncpy(fieldKv->key, lpField->key, kenLen); size_t numPoints = taosArrayGetSize(lpPoints);
fieldKv->key[kenLen] = '\0';
fieldKv->type = lpField->type; if (code != 0) {
fieldKv->length = lpField->length; goto cleanup;
fieldKv->value = malloc(fieldKv->length);
memcpy(fieldKv->value, lpField->value, fieldKv->length);
}
} }
taos_sml_insert(taos, points, (int)numPoints); TAOS_SML_DATA_POINT* points = TARRAY_GET_START(lpPoints);
code = taos_sml_insert(taos, points, (int)numPoints);
if (code != 0) {
tscError("taos_sml_insert error: %s", tstrerror((code)));
}
cleanup:
tscDebug("taos_insert_lines finish inserting %d lines. code: %d", numLines, code);
for (int i=0; i<numPoints; ++i) { for (int i=0; i<numPoints; ++i) {
destroySmlDataPoint(points+i); destroySmlDataPoint(points+i);
} }
free(points);
taosArrayDestroyEx(lpPoints, destroyLPPoint); taosArrayDestroy(lpPoints);
return 0; return code;
} }
...@@ -1617,6 +1617,8 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags ...@@ -1617,6 +1617,8 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
(*t1)->prevTS = INT64_MIN; (*t1)->prevTS = INT64_MIN;
} }
tsSetBlockInfo(pBlk, (*t1)->pTableMeta, pBlk->numOfRows);
taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES); taosHashPut(pCmd->insertParam.pTableBlockHashList, (void *)&pStmt->mtb.currentUid, sizeof(pStmt->mtb.currentUid), (void*)t1, POINTER_BYTES);
tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid); tscDebug("0x%"PRIx64" table:%s is already prepared, uid:%" PRIu64, pSql->self, name, pStmt->mtb.currentUid);
......
...@@ -4770,15 +4770,6 @@ static void freeContent(void* p) { ...@@ -4770,15 +4770,6 @@ static void freeContent(void* p) {
tfree(ptr); tfree(ptr);
} }
static int32_t contCompare(const void* p1, const void* p2) {
int32_t ret = strcmp(p1, p2);
if (ret == 0) {
return 0;
} else {
return ret > 0 ? 1:-1;
}
}
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray) { int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray) {
SSqlCmd *pCmd = &pSql->cmd; SSqlCmd *pCmd = &pSql->cmd;
...@@ -4826,7 +4817,7 @@ int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t lengt ...@@ -4826,7 +4817,7 @@ int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t lengt
} }
taosArraySort(pNameArray, nameComparFn); taosArraySort(pNameArray, nameComparFn);
taosArrayRemoveDuplicate(pNameArray, contCompare, freeContent); taosArrayRemoveDuplicate(pNameArray, nameComparFn, freeContent);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
......
...@@ -348,4 +348,13 @@ public class TSDBJNIConnector { ...@@ -348,4 +348,13 @@ public class TSDBJNIConnector {
} }
private native int closeStmt(long stmt, long con); private native int closeStmt(long stmt, long con);
public void insertLines(String[] lines) throws SQLException {
int code = insertLinesImp(lines, this.taos);
if (code != TSDBConstants.JNI_SUCCESS) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to insertLines");
}
}
private native int insertLinesImp(String[] lines, long conn);
} }
...@@ -114,6 +114,10 @@ public class TSDBJNIConnectorTest { ...@@ -114,6 +114,10 @@ public class TSDBJNIConnectorTest {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_RESULT_SET_NULL);
} }
// close statement // close statement
connector.executeQuery("use d");
String[] lines = new String[] {"st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000ns",
"st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000ns"};
connector.insertLines(lines);
// close connection // close connection
connector.closeConnection(); connector.closeConnection();
......
...@@ -403,6 +403,20 @@ class CTaosInterface(object): ...@@ -403,6 +403,20 @@ class CTaosInterface(object):
""" """
return CTaosInterface.libtaos.taos_affected_rows(result) return CTaosInterface.libtaos.taos_affected_rows(result)
@staticmethod
def insertLines(connection, lines):
'''
insert through lines protocol
@lines: list of str
@rtype: tsdb error codes
'''
numLines = len(lines)
c_lines_type = ctypes.c_char_p*numLines
c_lines = c_lines_type()
for i in range(numLines):
c_lines[i] = ctypes.c_char_p(lines[i].encode('utf-8'))
return CTaosInterface.libtaos.taos_insert_lines(connection, c_lines, ctypes.c_int(numLines))
@staticmethod @staticmethod
def subscribe(connection, restart, topic, sql, interval): def subscribe(connection, restart, topic, sql, interval):
"""Create a subscription """Create a subscription
......
...@@ -66,6 +66,14 @@ class TDengineConnection(object): ...@@ -66,6 +66,14 @@ class TDengineConnection(object):
self._conn, restart, topic, sql, interval) self._conn, restart, topic, sql, interval)
return TDengineSubscription(sub) return TDengineSubscription(sub)
def insertLines(self, lines):
"""
insert lines through line protocol
"""
if self._conn is None:
return None
return CTaosInterface.insertLines(self._conn, lines)
def cursor(self): def cursor(self):
"""Return a new Cursor object using the connection. """Return a new Cursor object using the connection.
""" """
......
...@@ -101,6 +101,7 @@ int32_t* taosGetErrno(); ...@@ -101,6 +101,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_TSC_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0218) //"Table does not exist") #define TSDB_CODE_TSC_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0218) //"Table does not exist")
#define TSDB_CODE_TSC_EXCEED_SQL_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0219) //"SQL statement too long check maxSQLLength config") #define TSDB_CODE_TSC_EXCEED_SQL_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0219) //"SQL statement too long check maxSQLLength config")
#define TSDB_CODE_TSC_FILE_EMPTY TAOS_DEF_ERROR_CODE(0, 0x021A) //"File is empty") #define TSDB_CODE_TSC_FILE_EMPTY TAOS_DEF_ERROR_CODE(0, 0x021A) //"File is empty")
#define TSDB_CODE_TSC_LINE_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x021B) //"Syntax error in Line")
// mnode // mnode
#define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed") #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed")
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
/* /*
when in some thread query return error, thread don't exit, but return, otherwise coredump in other thread. when in some thread query return error, thread don't exit, but return, otherwise coredump in other thread.
*/ */
#include <stdint.h> #include <stdint.h>
#include <taos.h> #include <taos.h>
...@@ -24,24 +24,24 @@ ...@@ -24,24 +24,24 @@
#define CURL_STATICLIB #define CURL_STATICLIB
#ifdef LINUX #ifdef LINUX
#include <argp.h> #include <argp.h>
#include <inttypes.h> #include <inttypes.h>
#ifndef _ALPINE #ifndef _ALPINE
#include <error.h> #include <error.h>
#endif #endif
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <wordexp.h> #include <wordexp.h>
#include <regex.h> #include <regex.h>
#else #else
#include <regex.h> #include <regex.h>
#include <stdio.h> #include <stdio.h>
#endif #endif
#include <assert.h> #include <assert.h>
...@@ -485,42 +485,42 @@ typedef unsigned __int32 uint32_t; ...@@ -485,42 +485,42 @@ typedef unsigned __int32 uint32_t;
#pragma comment ( lib, "ws2_32.lib" ) #pragma comment ( lib, "ws2_32.lib" )
// Some old MinGW/CYGWIN distributions don't define this: // Some old MinGW/CYGWIN distributions don't define this:
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif // ENABLE_VIRTUAL_TERMINAL_PROCESSING #endif // ENABLE_VIRTUAL_TERMINAL_PROCESSING
static HANDLE g_stdoutHandle; static HANDLE g_stdoutHandle;
static DWORD g_consoleMode; static DWORD g_consoleMode;
static void setupForAnsiEscape(void) { static void setupForAnsiEscape(void) {
DWORD mode = 0; DWORD mode = 0;
g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if(g_stdoutHandle == INVALID_HANDLE_VALUE) { if(g_stdoutHandle == INVALID_HANDLE_VALUE) {
exit(GetLastError()); exit(GetLastError());
} }
if(!GetConsoleMode(g_stdoutHandle, &mode)) { if(!GetConsoleMode(g_stdoutHandle, &mode)) {
exit(GetLastError()); exit(GetLastError());
} }
g_consoleMode = mode; g_consoleMode = mode;
// Enable ANSI escape codes // Enable ANSI escape codes
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if(!SetConsoleMode(g_stdoutHandle, mode)) { if(!SetConsoleMode(g_stdoutHandle, mode)) {
exit(GetLastError()); exit(GetLastError());
} }
} }
static void resetAfterAnsiEscape(void) { static void resetAfterAnsiEscape(void) {
// Reset colors // Reset colors
printf("\x1b[0m"); printf("\x1b[0m");
// Reset console mode // Reset console mode
if(!SetConsoleMode(g_stdoutHandle, g_consoleMode)) { if(!SetConsoleMode(g_stdoutHandle, g_consoleMode)) {
exit(GetLastError()); exit(GetLastError());
} }
} }
static int taosRandom() static int taosRandom()
...@@ -534,15 +534,15 @@ static int taosRandom() ...@@ -534,15 +534,15 @@ static int taosRandom()
static void setupForAnsiEscape(void) {} static void setupForAnsiEscape(void) {}
static void resetAfterAnsiEscape(void) { static void resetAfterAnsiEscape(void) {
// Reset colors // Reset colors
printf("\x1b[0m"); printf("\x1b[0m");
} }
#include <time.h> #include <time.h>
static int taosRandom() static int taosRandom()
{ {
return rand(); return rand();
} }
#endif // ifdef Windows #endif // ifdef Windows
...@@ -634,7 +634,7 @@ static FILE * g_fpOfInsertResult = NULL; ...@@ -634,7 +634,7 @@ static FILE * g_fpOfInsertResult = NULL;
#define debugPrint(fmt, ...) \ #define debugPrint(fmt, ...) \
do { if (g_args.debug_print || g_args.verbose_print) \ do { if (g_args.debug_print || g_args.verbose_print) \
fprintf(stderr, "DEBG: "fmt, __VA_ARGS__); } while(0) fprintf(stderr, "DEBG: "fmt, __VA_ARGS__); } while(0)
#define verbosePrint(fmt, ...) \ #define verbosePrint(fmt, ...) \
do { if (g_args.verbose_print) \ do { if (g_args.verbose_print) \
...@@ -1363,14 +1363,14 @@ static const char charNum[] = "0123456789"; ...@@ -1363,14 +1363,14 @@ static const char charNum[] = "0123456789";
static void nonrand_string(char *, int) __attribute__ ((unused)); // reserve for debugging purpose static void nonrand_string(char *, int) __attribute__ ((unused)); // reserve for debugging purpose
static void nonrand_string(char *str, int size) static void nonrand_string(char *str, int size)
{ {
str[0] = 0; str[0] = 0;
if (size > 0) { if (size > 0) {
int n; int n;
for (n = 0; n < size; n++) { for (n = 0; n < size; n++) {
str[n] = charNum[n % 10]; str[n] = charNum[n % 10];
} }
str[n] = 0; str[n] = 0;
} }
} }
#endif #endif
...@@ -1436,8 +1436,8 @@ static int printfInsertMeta() { ...@@ -1436,8 +1436,8 @@ static int printfInsertMeta() {
if (g_args.iface != INTERFACE_BUT) { if (g_args.iface != INTERFACE_BUT) {
// first time if no iface specified // first time if no iface specified
printf("interface: \033[33m%s\033[0m\n", printf("interface: \033[33m%s\033[0m\n",
(g_args.iface==TAOSC_IFACE)?"taosc": (g_args.iface==TAOSC_IFACE)?"taosc":
(g_args.iface==REST_IFACE)?"rest":"stmt"); (g_args.iface==REST_IFACE)?"rest":"stmt");
} }
printf("host: \033[33m%s:%u\033[0m\n", printf("host: \033[33m%s:%u\033[0m\n",
...@@ -2221,24 +2221,24 @@ static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port ...@@ -2221,24 +2221,24 @@ static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port
request_buf = malloc(req_buf_len); request_buf = malloc(req_buf_len);
if (NULL == request_buf) { if (NULL == request_buf) {
errorPrint("%s", "ERROR, cannot allocate memory.\n"); errorPrint("%s", "ERROR, cannot allocate memory.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
char userpass_buf[INPUT_BUF_LEN]; char userpass_buf[INPUT_BUF_LEN];
int mod_table[] = {0, 2, 1}; int mod_table[] = {0, 2, 1};
static char base64[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', static char base64[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'}; '4', '5', '6', '7', '8', '9', '+', '/'};
snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s",
g_Dbs.user, g_Dbs.password); g_Dbs.user, g_Dbs.password);
size_t userpass_buf_len = strlen(userpass_buf); size_t userpass_buf_len = strlen(userpass_buf);
size_t encoded_len = 4 * ((userpass_buf_len +2) / 3); size_t encoded_len = 4 * ((userpass_buf_len +2) / 3);
...@@ -2270,22 +2270,22 @@ static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port ...@@ -2270,22 +2270,22 @@ static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port
memset(base64_buf, 0, INPUT_BUF_LEN); memset(base64_buf, 0, INPUT_BUF_LEN);
for (int n = 0, m = 0; n < userpass_buf_len;) { for (int n = 0, m = 0; n < userpass_buf_len;) {
uint32_t oct_a = n < userpass_buf_len ? uint32_t oct_a = n < userpass_buf_len ?
(unsigned char) userpass_buf[n++]:0; (unsigned char) userpass_buf[n++]:0;
uint32_t oct_b = n < userpass_buf_len ? uint32_t oct_b = n < userpass_buf_len ?
(unsigned char) userpass_buf[n++]:0; (unsigned char) userpass_buf[n++]:0;
uint32_t oct_c = n < userpass_buf_len ? uint32_t oct_c = n < userpass_buf_len ?
(unsigned char) userpass_buf[n++]:0; (unsigned char) userpass_buf[n++]:0;
uint32_t triple = (oct_a << 0x10) + (oct_b << 0x08) + oct_c; uint32_t triple = (oct_a << 0x10) + (oct_b << 0x08) + oct_c;
base64_buf[m++] = base64[(triple >> 3* 6) & 0x3f]; base64_buf[m++] = base64[(triple >> 3* 6) & 0x3f];
base64_buf[m++] = base64[(triple >> 2* 6) & 0x3f]; base64_buf[m++] = base64[(triple >> 2* 6) & 0x3f];
base64_buf[m++] = base64[(triple >> 1* 6) & 0x3f]; base64_buf[m++] = base64[(triple >> 1* 6) & 0x3f];
base64_buf[m++] = base64[(triple >> 0* 6) & 0x3f]; base64_buf[m++] = base64[(triple >> 0* 6) & 0x3f];
} }
for (int l = 0; l < mod_table[userpass_buf_len % 3]; l++) for (int l = 0; l < mod_table[userpass_buf_len % 3]; l++)
base64_buf[encoded_len - 1 - l] = '='; base64_buf[encoded_len - 1 - l] = '=';
debugPrint("%s() LN%d: auth string base64 encoded: %s\n", debugPrint("%s() LN%d: auth string base64 encoded: %s\n",
__func__, __LINE__, base64_buf); __func__, __LINE__, base64_buf);
...@@ -2343,7 +2343,7 @@ static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port ...@@ -2343,7 +2343,7 @@ static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port
printf("Response:\n%s\n", response_buf); printf("Response:\n%s\n", response_buf);
if (strlen(pThreadInfo->filePath) > 0) { if (strlen(pThreadInfo->filePath) > 0) {
appendResultBufToFile(response_buf, pThreadInfo); appendResultBufToFile(response_buf, pThreadInfo);
} }
free(request_buf); free(request_buf);
...@@ -2425,11 +2425,11 @@ static char* generateTagValuesForStb(SSuperTable* stbInfo, int64_t tableSeq) { ...@@ -2425,11 +2425,11 @@ static char* generateTagValuesForStb(SSuperTable* stbInfo, int64_t tableSeq) {
if ((g_args.demo_mode) && (i == 0)) { if ((g_args.demo_mode) && (i == 0)) {
dataLen += snprintf(dataBuf + dataLen, dataLen += snprintf(dataBuf + dataLen,
TSDB_MAX_SQL_LEN - dataLen, TSDB_MAX_SQL_LEN - dataLen,
"%"PRId64",", tableSeq % 10); "%"PRId64",", tableSeq % 10);
} else { } else {
dataLen += snprintf(dataBuf + dataLen, dataLen += snprintf(dataBuf + dataLen,
TSDB_MAX_SQL_LEN - dataLen, TSDB_MAX_SQL_LEN - dataLen,
"%"PRId64",", tableSeq); "%"PRId64",", tableSeq);
} }
} else if (0 == strncasecmp(stbInfo->tags[i].dataType, } else if (0 == strncasecmp(stbInfo->tags[i].dataType,
"bigint", strlen("bigint"))) { "bigint", strlen("bigint"))) {
...@@ -2472,72 +2472,72 @@ static char* generateTagValuesForStb(SSuperTable* stbInfo, int64_t tableSeq) { ...@@ -2472,72 +2472,72 @@ static char* generateTagValuesForStb(SSuperTable* stbInfo, int64_t tableSeq) {
} }
static int calcRowLen(SSuperTable* superTbls) { static int calcRowLen(SSuperTable* superTbls) {
int colIndex; int colIndex;
int lenOfOneRow = 0; int lenOfOneRow = 0;
for (colIndex = 0; colIndex < superTbls->columnCount; colIndex++) { for (colIndex = 0; colIndex < superTbls->columnCount; colIndex++) {
char* dataType = superTbls->columns[colIndex].dataType; char* dataType = superTbls->columns[colIndex].dataType;
if (strcasecmp(dataType, "BINARY") == 0) { if (strcasecmp(dataType, "BINARY") == 0) {
lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; lenOfOneRow += superTbls->columns[colIndex].dataLen + 3;
} else if (strcasecmp(dataType, "NCHAR") == 0) { } else if (strcasecmp(dataType, "NCHAR") == 0) {
lenOfOneRow += superTbls->columns[colIndex].dataLen + 3; lenOfOneRow += superTbls->columns[colIndex].dataLen + 3;
} else if (strcasecmp(dataType, "INT") == 0) { } else if (strcasecmp(dataType, "INT") == 0) {
lenOfOneRow += 11; lenOfOneRow += 11;
} else if (strcasecmp(dataType, "BIGINT") == 0) { } else if (strcasecmp(dataType, "BIGINT") == 0) {
lenOfOneRow += 21; lenOfOneRow += 21;
} else if (strcasecmp(dataType, "SMALLINT") == 0) { } else if (strcasecmp(dataType, "SMALLINT") == 0) {
lenOfOneRow += 6; lenOfOneRow += 6;
} else if (strcasecmp(dataType, "TINYINT") == 0) { } else if (strcasecmp(dataType, "TINYINT") == 0) {
lenOfOneRow += 4; lenOfOneRow += 4;
} else if (strcasecmp(dataType, "BOOL") == 0) { } else if (strcasecmp(dataType, "BOOL") == 0) {
lenOfOneRow += 6; lenOfOneRow += 6;
} else if (strcasecmp(dataType, "FLOAT") == 0) { } else if (strcasecmp(dataType, "FLOAT") == 0) {
lenOfOneRow += 22; lenOfOneRow += 22;
} else if (strcasecmp(dataType, "DOUBLE") == 0) { } else if (strcasecmp(dataType, "DOUBLE") == 0) {
lenOfOneRow += 42; lenOfOneRow += 42;
} else if (strcasecmp(dataType, "TIMESTAMP") == 0) { } else if (strcasecmp(dataType, "TIMESTAMP") == 0) {
lenOfOneRow += 21; lenOfOneRow += 21;
} else { } else {
printf("get error data type : %s\n", dataType); printf("get error data type : %s\n", dataType);
exit(-1); exit(-1);
} }
} }
superTbls->lenOfOneRow = lenOfOneRow + 20; // timestamp superTbls->lenOfOneRow = lenOfOneRow + 20; // timestamp
int tagIndex; int tagIndex;
int lenOfTagOfOneRow = 0; int lenOfTagOfOneRow = 0;
for (tagIndex = 0; tagIndex < superTbls->tagCount; tagIndex++) { for (tagIndex = 0; tagIndex < superTbls->tagCount; tagIndex++) {
char* dataType = superTbls->tags[tagIndex].dataType; char* dataType = superTbls->tags[tagIndex].dataType;
if (strcasecmp(dataType, "BINARY") == 0) { if (strcasecmp(dataType, "BINARY") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3;
} else if (strcasecmp(dataType, "NCHAR") == 0) { } else if (strcasecmp(dataType, "NCHAR") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3;
} else if (strcasecmp(dataType, "INT") == 0) { } else if (strcasecmp(dataType, "INT") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 11; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 11;
} else if (strcasecmp(dataType, "BIGINT") == 0) { } else if (strcasecmp(dataType, "BIGINT") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 21; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 21;
} else if (strcasecmp(dataType, "SMALLINT") == 0) { } else if (strcasecmp(dataType, "SMALLINT") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6;
} else if (strcasecmp(dataType, "TINYINT") == 0) { } else if (strcasecmp(dataType, "TINYINT") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 4; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 4;
} else if (strcasecmp(dataType, "BOOL") == 0) { } else if (strcasecmp(dataType, "BOOL") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6;
} else if (strcasecmp(dataType, "FLOAT") == 0) { } else if (strcasecmp(dataType, "FLOAT") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 22; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 22;
} else if (strcasecmp(dataType, "DOUBLE") == 0) { } else if (strcasecmp(dataType, "DOUBLE") == 0) {
lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 42; lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 42;
} else { } else {
printf("get error tag type : %s\n", dataType); printf("get error tag type : %s\n", dataType);
exit(-1); exit(-1);
}
} }
}
superTbls->lenOfTagOfOneRow = lenOfTagOfOneRow; superTbls->lenOfTagOfOneRow = lenOfTagOfOneRow;
return 0; return 0;
} }
...@@ -2545,84 +2545,84 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, ...@@ -2545,84 +2545,84 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos,
char* dbName, char* sTblName, char** childTblNameOfSuperTbl, char* dbName, char* sTblName, char** childTblNameOfSuperTbl,
int64_t* childTblCountOfSuperTbl, int64_t limit, uint64_t offset) { int64_t* childTblCountOfSuperTbl, int64_t limit, uint64_t offset) {
char command[BUFFER_SIZE] = "\0"; char command[BUFFER_SIZE] = "\0";
char limitBuf[100] = "\0"; char limitBuf[100] = "\0";
TAOS_RES * res; TAOS_RES * res;
TAOS_ROW row = NULL; TAOS_ROW row = NULL;
char* childTblName = *childTblNameOfSuperTbl; char* childTblName = *childTblNameOfSuperTbl;
if (offset >= 0) { if (offset >= 0) {
snprintf(limitBuf, 100, " limit %"PRId64" offset %"PRIu64"", snprintf(limitBuf, 100, " limit %"PRId64" offset %"PRIu64"",
limit, offset); limit, offset);
} }
//get all child table name use cmd: select tbname from superTblName; //get all child table name use cmd: select tbname from superTblName;
snprintf(command, BUFFER_SIZE, "select tbname from %s.%s %s", snprintf(command, BUFFER_SIZE, "select tbname from %s.%s %s",
dbName, sTblName, limitBuf); dbName, sTblName, limitBuf);
res = taos_query(taos, command); res = taos_query(taos, command);
int32_t code = taos_errno(res); int32_t code = taos_errno(res);
if (code != 0) { if (code != 0) {
taos_free_result(res); taos_free_result(res);
taos_close(taos);
errorPrint("%s() LN%d, failed to run command %s\n",
__func__, __LINE__, command);
exit(-1);
}
int64_t childTblCount = (limit < 0)?10000:limit;
int64_t count = 0;
if (childTblName == NULL) {
childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN);
if (NULL == childTblName) {
taos_free_result(res);
taos_close(taos); taos_close(taos);
errorPrint("%s() LN%d, failed to allocate memory!\n", __func__, __LINE__); errorPrint("%s() LN%d, failed to run command %s\n",
__func__, __LINE__, command);
exit(-1); exit(-1);
} }
}
char* pTblName = childTblName;
while((row = taos_fetch_row(res)) != NULL) {
int32_t* len = taos_fetch_lengths(res);
if (0 == strlen((char *)row[0])) { int64_t childTblCount = (limit < 0)?10000:limit;
errorPrint("%s() LN%d, No.%"PRId64" table return empty name\n", int64_t count = 0;
__func__, __LINE__, count); if (childTblName == NULL) {
exit(-1); childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN);
if (NULL == childTblName) {
taos_free_result(res);
taos_close(taos);
errorPrint("%s() LN%d, failed to allocate memory!\n", __func__, __LINE__);
exit(-1);
}
} }
tstrncpy(pTblName, (char *)row[0], len[0]+1); char* pTblName = childTblName;
//printf("==== sub table name: %s\n", pTblName); while((row = taos_fetch_row(res)) != NULL) {
count++; int32_t* len = taos_fetch_lengths(res);
if (count >= childTblCount - 1) {
char *tmp = realloc(childTblName, if (0 == strlen((char *)row[0])) {
(size_t)childTblCount*1.5*TSDB_TABLE_NAME_LEN+1); errorPrint("%s() LN%d, No.%"PRId64" table return empty name\n",
if (tmp != NULL) { __func__, __LINE__, count);
childTblName = tmp; exit(-1);
childTblCount = (int)(childTblCount*1.5); }
memset(childTblName + count*TSDB_TABLE_NAME_LEN, 0,
(size_t)((childTblCount-count)*TSDB_TABLE_NAME_LEN)); tstrncpy(pTblName, (char *)row[0], len[0]+1);
} else { //printf("==== sub table name: %s\n", pTblName);
// exit, if allocate more memory failed count++;
errorPrint("%s() LN%d, realloc fail for save child table name of %s.%s\n", if (count >= childTblCount - 1) {
__func__, __LINE__, dbName, sTblName); char *tmp = realloc(childTblName,
tmfree(childTblName); (size_t)childTblCount*1.5*TSDB_TABLE_NAME_LEN+1);
taos_free_result(res); if (tmp != NULL) {
taos_close(taos); childTblName = tmp;
exit(-1); childTblCount = (int)(childTblCount*1.5);
} memset(childTblName + count*TSDB_TABLE_NAME_LEN, 0,
(size_t)((childTblCount-count)*TSDB_TABLE_NAME_LEN));
} else {
// exit, if allocate more memory failed
errorPrint("%s() LN%d, realloc fail for save child table name of %s.%s\n",
__func__, __LINE__, dbName, sTblName);
tmfree(childTblName);
taos_free_result(res);
taos_close(taos);
exit(-1);
}
}
pTblName = childTblName + count * TSDB_TABLE_NAME_LEN;
} }
pTblName = childTblName + count * TSDB_TABLE_NAME_LEN;
}
*childTblCountOfSuperTbl = count; *childTblCountOfSuperTbl = count;
*childTblNameOfSuperTbl = childTblName; *childTblNameOfSuperTbl = childTblName;
taos_free_result(res); taos_free_result(res);
return 0; return 0;
} }
static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName, static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName,
...@@ -2637,82 +2637,82 @@ static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName, ...@@ -2637,82 +2637,82 @@ static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName,
static int getSuperTableFromServer(TAOS * taos, char* dbName, static int getSuperTableFromServer(TAOS * taos, char* dbName,
SSuperTable* superTbls) { SSuperTable* superTbls) {
char command[BUFFER_SIZE] = "\0"; char command[BUFFER_SIZE] = "\0";
TAOS_RES * res; TAOS_RES * res;
TAOS_ROW row = NULL; TAOS_ROW row = NULL;
int count = 0; int count = 0;
//get schema use cmd: describe superTblName; //get schema use cmd: describe superTblName;
snprintf(command, BUFFER_SIZE, "describe %s.%s", dbName, superTbls->sTblName); snprintf(command, BUFFER_SIZE, "describe %s.%s", dbName, superTbls->sTblName);
res = taos_query(taos, command); res = taos_query(taos, command);
int32_t code = taos_errno(res); int32_t code = taos_errno(res);
if (code != 0) { if (code != 0) {
printf("failed to run command %s\n", command); printf("failed to run command %s\n", command);
taos_free_result(res);
return -1;
}
int tagIndex = 0;
int columnIndex = 0;
TAOS_FIELD *fields = taos_fetch_fields(res);
while((row = taos_fetch_row(res)) != NULL) {
if (0 == count) {
count++;
continue;
}
if (strcmp((char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], "TAG") == 0) {
tstrncpy(superTbls->tags[tagIndex].field,
(char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
tstrncpy(superTbls->tags[tagIndex].dataType,
(char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
min(15, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes));
superTbls->tags[tagIndex].dataLen =
*((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
tstrncpy(superTbls->tags[tagIndex].note,
(char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
tagIndex++;
} else {
tstrncpy(superTbls->columns[columnIndex].field,
(char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
tstrncpy(superTbls->columns[columnIndex].dataType,
(char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
min(15, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes));
superTbls->columns[columnIndex].dataLen =
*((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
tstrncpy(superTbls->columns[columnIndex].note,
(char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
columnIndex++;
}
count++;
}
superTbls->columnCount = columnIndex;
superTbls->tagCount = tagIndex;
taos_free_result(res); taos_free_result(res);
return -1;
}
int tagIndex = 0;
int columnIndex = 0;
TAOS_FIELD *fields = taos_fetch_fields(res);
while((row = taos_fetch_row(res)) != NULL) {
if (0 == count) {
count++;
continue;
}
if (strcmp((char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], "TAG") == 0) {
tstrncpy(superTbls->tags[tagIndex].field,
(char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
tstrncpy(superTbls->tags[tagIndex].dataType,
(char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
min(15, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes));
superTbls->tags[tagIndex].dataLen =
*((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
tstrncpy(superTbls->tags[tagIndex].note,
(char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
tagIndex++;
} else {
tstrncpy(superTbls->columns[columnIndex].field,
(char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
tstrncpy(superTbls->columns[columnIndex].dataType,
(char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
min(15, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes));
superTbls->columns[columnIndex].dataLen =
*((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
tstrncpy(superTbls->columns[columnIndex].note,
(char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
columnIndex++;
}
count++;
}
superTbls->columnCount = columnIndex;
superTbls->tagCount = tagIndex;
taos_free_result(res);
calcRowLen(superTbls);
/* calcRowLen(superTbls);
if (TBL_ALREADY_EXISTS == superTbls->childTblExists) {
/*
if (TBL_ALREADY_EXISTS == superTbls->childTblExists) {
//get all child table name use cmd: select tbname from superTblName; //get all child table name use cmd: select tbname from superTblName;
int childTblCount = 10000; int childTblCount = 10000;
superTbls->childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN); superTbls->childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN);
if (superTbls->childTblName == NULL) { if (superTbls->childTblName == NULL) {
errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__); errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__);
return -1; return -1;
} }
getAllChildNameOfSuperTable(taos, dbName, getAllChildNameOfSuperTable(taos, dbName,
superTbls->sTblName, superTbls->sTblName,
&superTbls->childTblName, &superTbls->childTblName,
&superTbls->childTblCount); &superTbls->childTblCount);
} }
*/ */
return 0; return 0;
} }
static int createSuperTable( static int createSuperTable(
...@@ -2748,8 +2748,8 @@ static int createSuperTable( ...@@ -2748,8 +2748,8 @@ static int createSuperTable(
lenOfOneRow += superTbl->columns[colIndex].dataLen + 3; lenOfOneRow += superTbl->columns[colIndex].dataLen + 3;
} else if (strcasecmp(dataType, "INT") == 0) { } else if (strcasecmp(dataType, "INT") == 0) {
if ((g_args.demo_mode) && (colIndex == 1)) { if ((g_args.demo_mode) && (colIndex == 1)) {
len += snprintf(cols + len, COL_BUFFER_LEN - len, len += snprintf(cols + len, COL_BUFFER_LEN - len,
", VOLTAGE INT"); ", VOLTAGE INT");
} else { } else {
len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "INT"); len += snprintf(cols + len, COL_BUFFER_LEN - len, ",C%d %s", colIndex, "INT");
} }
...@@ -3221,7 +3221,7 @@ static void createChildTables() { ...@@ -3221,7 +3221,7 @@ static void createChildTables() {
continue; continue;
} }
verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, verbosePrint("%s() LN%d: %s\n", __func__, __LINE__,
g_Dbs.db[i].superTbls[j].colsOfCreateChildTable); g_Dbs.db[i].superTbls[j].colsOfCreateChildTable);
uint64_t startFrom = 0; uint64_t startFrom = 0;
g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount; g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount;
...@@ -3269,295 +3269,295 @@ static void createChildTables() { ...@@ -3269,295 +3269,295 @@ static void createChildTables() {
} }
/* /*
Read 10000 lines at most. If more than 10000 lines, continue to read after using Read 10000 lines at most. If more than 10000 lines, continue to read after using
*/ */
static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) { static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) {
size_t n = 0; size_t n = 0;
ssize_t readLen = 0; ssize_t readLen = 0;
char * line = NULL; char * line = NULL;
FILE *fp = fopen(superTblInfo->tagsFile, "r");
if (fp == NULL) {
printf("Failed to open tags file: %s, reason:%s\n",
superTblInfo->tagsFile, strerror(errno));
return -1;
}
if (superTblInfo->tagDataBuf) {
free(superTblInfo->tagDataBuf);
superTblInfo->tagDataBuf = NULL;
}
int tagCount = 10000;
int count = 0;
char* tagDataBuf = calloc(1, superTblInfo->lenOfTagOfOneRow * tagCount);
if (tagDataBuf == NULL) {
printf("Failed to calloc, reason:%s\n", strerror(errno));
fclose(fp);
return -1;
}
while((readLen = tgetline(&line, &n, fp)) != -1) { FILE *fp = fopen(superTblInfo->tagsFile, "r");
if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) { if (fp == NULL) {
line[--readLen] = 0; printf("Failed to open tags file: %s, reason:%s\n",
superTblInfo->tagsFile, strerror(errno));
return -1;
} }
if (readLen == 0) { if (superTblInfo->tagDataBuf) {
continue; free(superTblInfo->tagDataBuf);
superTblInfo->tagDataBuf = NULL;
} }
memcpy(tagDataBuf + count * superTblInfo->lenOfTagOfOneRow, line, readLen); int tagCount = 10000;
count++; int count = 0;
char* tagDataBuf = calloc(1, superTblInfo->lenOfTagOfOneRow * tagCount);
if (count >= tagCount - 1) { if (tagDataBuf == NULL) {
char *tmp = realloc(tagDataBuf, printf("Failed to calloc, reason:%s\n", strerror(errno));
(size_t)tagCount*1.5*superTblInfo->lenOfTagOfOneRow);
if (tmp != NULL) {
tagDataBuf = tmp;
tagCount = (int)(tagCount*1.5);
memset(tagDataBuf + count*superTblInfo->lenOfTagOfOneRow,
0, (size_t)((tagCount-count)*superTblInfo->lenOfTagOfOneRow));
} else {
// exit, if allocate more memory failed
printf("realloc fail for save tag val from %s\n", superTblInfo->tagsFile);
tmfree(tagDataBuf);
free(line);
fclose(fp); fclose(fp);
return -1; return -1;
}
} }
}
superTblInfo->tagDataBuf = tagDataBuf; while((readLen = tgetline(&line, &n, fp)) != -1) {
superTblInfo->tagSampleCount = count; if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
line[--readLen] = 0;
}
if (readLen == 0) {
continue;
}
memcpy(tagDataBuf + count * superTblInfo->lenOfTagOfOneRow, line, readLen);
count++;
if (count >= tagCount - 1) {
char *tmp = realloc(tagDataBuf,
(size_t)tagCount*1.5*superTblInfo->lenOfTagOfOneRow);
if (tmp != NULL) {
tagDataBuf = tmp;
tagCount = (int)(tagCount*1.5);
memset(tagDataBuf + count*superTblInfo->lenOfTagOfOneRow,
0, (size_t)((tagCount-count)*superTblInfo->lenOfTagOfOneRow));
} else {
// exit, if allocate more memory failed
printf("realloc fail for save tag val from %s\n", superTblInfo->tagsFile);
tmfree(tagDataBuf);
free(line);
fclose(fp);
return -1;
}
}
}
free(line); superTblInfo->tagDataBuf = tagDataBuf;
fclose(fp); superTblInfo->tagSampleCount = count;
return 0;
free(line);
fclose(fp);
return 0;
} }
/* /*
Read 10000 lines at most. If more than 10000 lines, continue to read after using Read 10000 lines at most. If more than 10000 lines, continue to read after using
*/ */
static int readSampleFromCsvFileToMem( static int readSampleFromCsvFileToMem(
SSuperTable* superTblInfo) { SSuperTable* superTblInfo) {
size_t n = 0; size_t n = 0;
ssize_t readLen = 0; ssize_t readLen = 0;
char * line = NULL; char * line = NULL;
int getRows = 0; int getRows = 0;
FILE* fp = fopen(superTblInfo->sampleFile, "r"); FILE* fp = fopen(superTblInfo->sampleFile, "r");
if (fp == NULL) { if (fp == NULL) {
errorPrint( "Failed to open sample file: %s, reason:%s\n", errorPrint( "Failed to open sample file: %s, reason:%s\n",
superTblInfo->sampleFile, strerror(errno));
return -1;
}
assert(superTblInfo->sampleDataBuf);
memset(superTblInfo->sampleDataBuf, 0,
MAX_SAMPLES_ONCE_FROM_FILE * superTblInfo->lenOfOneRow);
while(1) {
readLen = tgetline(&line, &n, fp);
if (-1 == readLen) {
if(0 != fseek(fp, 0, SEEK_SET)) {
errorPrint( "Failed to fseek file: %s, reason:%s\n",
superTblInfo->sampleFile, strerror(errno)); superTblInfo->sampleFile, strerror(errno));
fclose(fp);
return -1; return -1;
}
continue;
} }
if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) { assert(superTblInfo->sampleDataBuf);
line[--readLen] = 0; memset(superTblInfo->sampleDataBuf, 0,
} MAX_SAMPLES_ONCE_FROM_FILE * superTblInfo->lenOfOneRow);
while(1) {
readLen = tgetline(&line, &n, fp);
if (-1 == readLen) {
if(0 != fseek(fp, 0, SEEK_SET)) {
errorPrint( "Failed to fseek file: %s, reason:%s\n",
superTblInfo->sampleFile, strerror(errno));
fclose(fp);
return -1;
}
continue;
}
if (readLen == 0) { if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
continue; line[--readLen] = 0;
} }
if (readLen > superTblInfo->lenOfOneRow) { if (readLen == 0) {
printf("sample row len[%d] overflow define schema len[%"PRIu64"], so discard this row\n", continue;
(int32_t)readLen, superTblInfo->lenOfOneRow); }
continue;
}
memcpy(superTblInfo->sampleDataBuf + getRows * superTblInfo->lenOfOneRow, if (readLen > superTblInfo->lenOfOneRow) {
line, readLen); printf("sample row len[%d] overflow define schema len[%"PRIu64"], so discard this row\n",
getRows++; (int32_t)readLen, superTblInfo->lenOfOneRow);
continue;
}
if (getRows == MAX_SAMPLES_ONCE_FROM_FILE) { memcpy(superTblInfo->sampleDataBuf + getRows * superTblInfo->lenOfOneRow,
break; line, readLen);
getRows++;
if (getRows == MAX_SAMPLES_ONCE_FROM_FILE) {
break;
}
} }
}
fclose(fp); fclose(fp);
tmfree(line); tmfree(line);
return 0; return 0;
} }
static bool getColumnAndTagTypeFromInsertJsonFile( static bool getColumnAndTagTypeFromInsertJsonFile(
cJSON* stbInfo, SSuperTable* superTbls) { cJSON* stbInfo, SSuperTable* superTbls) {
bool ret = false; bool ret = false;
// columns // columns
cJSON *columns = cJSON_GetObjectItem(stbInfo, "columns"); cJSON *columns = cJSON_GetObjectItem(stbInfo, "columns");
if (columns && columns->type != cJSON_Array) { if (columns && columns->type != cJSON_Array) {
printf("ERROR: failed to read json, columns not found\n"); printf("ERROR: failed to read json, columns not found\n");
goto PARSE_OVER; goto PARSE_OVER;
} else if (NULL == columns) { } else if (NULL == columns) {
superTbls->columnCount = 0; superTbls->columnCount = 0;
superTbls->tagCount = 0; superTbls->tagCount = 0;
return true; return true;
} }
int columnSize = cJSON_GetArraySize(columns); int columnSize = cJSON_GetArraySize(columns);
if ((columnSize + 1/* ts */) > TSDB_MAX_COLUMNS) { if ((columnSize + 1/* ts */) > TSDB_MAX_COLUMNS) {
errorPrint("%s() LN%d, failed to read json, column size overflow, max column size is %d\n", errorPrint("%s() LN%d, failed to read json, column size overflow, max column size is %d\n",
__func__, __LINE__, TSDB_MAX_COLUMNS); __func__, __LINE__, TSDB_MAX_COLUMNS);
goto PARSE_OVER; goto PARSE_OVER;
} }
int count = 1; int count = 1;
int index = 0; int index = 0;
StrColumn columnCase; StrColumn columnCase;
//superTbls->columnCount = columnSize; //superTbls->columnCount = columnSize;
for (int k = 0; k < columnSize; ++k) { for (int k = 0; k < columnSize; ++k) {
cJSON* column = cJSON_GetArrayItem(columns, k); cJSON* column = cJSON_GetArrayItem(columns, k);
if (column == NULL) continue; if (column == NULL) continue;
count = 1; count = 1;
cJSON* countObj = cJSON_GetObjectItem(column, "count"); cJSON* countObj = cJSON_GetObjectItem(column, "count");
if (countObj && countObj->type == cJSON_Number) { if (countObj && countObj->type == cJSON_Number) {
count = countObj->valueint; count = countObj->valueint;
} else if (countObj && countObj->type != cJSON_Number) { } else if (countObj && countObj->type != cJSON_Number) {
errorPrint("%s() LN%d, failed to read json, column count not found\n", errorPrint("%s() LN%d, failed to read json, column count not found\n",
__func__, __LINE__); __func__, __LINE__);
goto PARSE_OVER; goto PARSE_OVER;
} else { } else {
count = 1; count = 1;
} }
// column info // column info
memset(&columnCase, 0, sizeof(StrColumn)); memset(&columnCase, 0, sizeof(StrColumn));
cJSON *dataType = cJSON_GetObjectItem(column, "type"); cJSON *dataType = cJSON_GetObjectItem(column, "type");
if (!dataType || dataType->type != cJSON_String if (!dataType || dataType->type != cJSON_String
|| dataType->valuestring == NULL) { || dataType->valuestring == NULL) {
errorPrint("%s() LN%d: failed to read json, column type not found\n", errorPrint("%s() LN%d: failed to read json, column type not found\n",
__func__, __LINE__); __func__, __LINE__);
goto PARSE_OVER; goto PARSE_OVER;
} }
//tstrncpy(superTbls->columns[k].dataType, dataType->valuestring, MAX_TB_NAME_SIZE); //tstrncpy(superTbls->columns[k].dataType, dataType->valuestring, MAX_TB_NAME_SIZE);
tstrncpy(columnCase.dataType, dataType->valuestring, strlen(dataType->valuestring) + 1); tstrncpy(columnCase.dataType, dataType->valuestring, strlen(dataType->valuestring) + 1);
cJSON* dataLen = cJSON_GetObjectItem(column, "len"); cJSON* dataLen = cJSON_GetObjectItem(column, "len");
if (dataLen && dataLen->type == cJSON_Number) { if (dataLen && dataLen->type == cJSON_Number) {
columnCase.dataLen = dataLen->valueint; columnCase.dataLen = dataLen->valueint;
} else if (dataLen && dataLen->type != cJSON_Number) { } else if (dataLen && dataLen->type != cJSON_Number) {
debugPrint("%s() LN%d: failed to read json, column len not found\n", debugPrint("%s() LN%d: failed to read json, column len not found\n",
__func__, __LINE__); __func__, __LINE__);
goto PARSE_OVER; goto PARSE_OVER;
} else { } else {
columnCase.dataLen = 8; columnCase.dataLen = 8;
} }
for (int n = 0; n < count; ++n) { for (int n = 0; n < count; ++n) {
tstrncpy(superTbls->columns[index].dataType, tstrncpy(superTbls->columns[index].dataType,
columnCase.dataType, strlen(columnCase.dataType) + 1); columnCase.dataType, strlen(columnCase.dataType) + 1);
superTbls->columns[index].dataLen = columnCase.dataLen; superTbls->columns[index].dataLen = columnCase.dataLen;
index++; index++;
} }
} }
if ((index + 1 /* ts */) > MAX_NUM_COLUMNS) { if ((index + 1 /* ts */) > MAX_NUM_COLUMNS) {
errorPrint("%s() LN%d, failed to read json, column size overflow, allowed max column size is %d\n", errorPrint("%s() LN%d, failed to read json, column size overflow, allowed max column size is %d\n",
__func__, __LINE__, MAX_NUM_COLUMNS); __func__, __LINE__, MAX_NUM_COLUMNS);
goto PARSE_OVER; goto PARSE_OVER;
} }
superTbls->columnCount = index; superTbls->columnCount = index;
count = 1;
index = 0;
// tags
cJSON *tags = cJSON_GetObjectItem(stbInfo, "tags");
if (!tags || tags->type != cJSON_Array) {
errorPrint("%s() LN%d, failed to read json, tags not found\n",
__func__, __LINE__);
goto PARSE_OVER;
}
int tagSize = cJSON_GetArraySize(tags);
if (tagSize > TSDB_MAX_TAGS) {
errorPrint("%s() LN%d, failed to read json, tags size overflow, max tag size is %d\n",
__func__, __LINE__, TSDB_MAX_TAGS);
goto PARSE_OVER;
}
//superTbls->tagCount = tagSize;
for (int k = 0; k < tagSize; ++k) {
cJSON* tag = cJSON_GetArrayItem(tags, k);
if (tag == NULL) continue;
count = 1; count = 1;
cJSON* countObj = cJSON_GetObjectItem(tag, "count"); index = 0;
if (countObj && countObj->type == cJSON_Number) { // tags
count = countObj->valueint; cJSON *tags = cJSON_GetObjectItem(stbInfo, "tags");
} else if (countObj && countObj->type != cJSON_Number) { if (!tags || tags->type != cJSON_Array) {
printf("ERROR: failed to read json, column count not found\n"); errorPrint("%s() LN%d, failed to read json, tags not found\n",
goto PARSE_OVER; __func__, __LINE__);
} else { goto PARSE_OVER;
count = 1; }
}
int tagSize = cJSON_GetArraySize(tags);
// column info if (tagSize > TSDB_MAX_TAGS) {
memset(&columnCase, 0, sizeof(StrColumn)); errorPrint("%s() LN%d, failed to read json, tags size overflow, max tag size is %d\n",
cJSON *dataType = cJSON_GetObjectItem(tag, "type"); __func__, __LINE__, TSDB_MAX_TAGS);
if (!dataType || dataType->type != cJSON_String goto PARSE_OVER;
|| dataType->valuestring == NULL) {
errorPrint("%s() LN%d, failed to read json, tag type not found\n",
__func__, __LINE__);
goto PARSE_OVER;
}
tstrncpy(columnCase.dataType, dataType->valuestring, strlen(dataType->valuestring) + 1);
cJSON* dataLen = cJSON_GetObjectItem(tag, "len");
if (dataLen && dataLen->type == cJSON_Number) {
columnCase.dataLen = dataLen->valueint;
} else if (dataLen && dataLen->type != cJSON_Number) {
errorPrint("%s() LN%d, failed to read json, column len not found\n",
__func__, __LINE__);
goto PARSE_OVER;
} else {
columnCase.dataLen = 0;
} }
for (int n = 0; n < count; ++n) { //superTbls->tagCount = tagSize;
tstrncpy(superTbls->tags[index].dataType, columnCase.dataType, for (int k = 0; k < tagSize; ++k) {
strlen(columnCase.dataType) + 1); cJSON* tag = cJSON_GetArrayItem(tags, k);
superTbls->tags[index].dataLen = columnCase.dataLen; if (tag == NULL) continue;
index++;
count = 1;
cJSON* countObj = cJSON_GetObjectItem(tag, "count");
if (countObj && countObj->type == cJSON_Number) {
count = countObj->valueint;
} else if (countObj && countObj->type != cJSON_Number) {
printf("ERROR: failed to read json, column count not found\n");
goto PARSE_OVER;
} else {
count = 1;
}
// column info
memset(&columnCase, 0, sizeof(StrColumn));
cJSON *dataType = cJSON_GetObjectItem(tag, "type");
if (!dataType || dataType->type != cJSON_String
|| dataType->valuestring == NULL) {
errorPrint("%s() LN%d, failed to read json, tag type not found\n",
__func__, __LINE__);
goto PARSE_OVER;
}
tstrncpy(columnCase.dataType, dataType->valuestring, strlen(dataType->valuestring) + 1);
cJSON* dataLen = cJSON_GetObjectItem(tag, "len");
if (dataLen && dataLen->type == cJSON_Number) {
columnCase.dataLen = dataLen->valueint;
} else if (dataLen && dataLen->type != cJSON_Number) {
errorPrint("%s() LN%d, failed to read json, column len not found\n",
__func__, __LINE__);
goto PARSE_OVER;
} else {
columnCase.dataLen = 0;
}
for (int n = 0; n < count; ++n) {
tstrncpy(superTbls->tags[index].dataType, columnCase.dataType,
strlen(columnCase.dataType) + 1);
superTbls->tags[index].dataLen = columnCase.dataLen;
index++;
}
} }
}
if (index > TSDB_MAX_TAGS) { if (index > TSDB_MAX_TAGS) {
errorPrint("%s() LN%d, failed to read json, tags size overflow, allowed max tag count is %d\n", errorPrint("%s() LN%d, failed to read json, tags size overflow, allowed max tag count is %d\n",
__func__, __LINE__, TSDB_MAX_TAGS); __func__, __LINE__, TSDB_MAX_TAGS);
goto PARSE_OVER; goto PARSE_OVER;
} }
superTbls->tagCount = index; superTbls->tagCount = index;
if ((superTbls->columnCount + superTbls->tagCount + 1 /* ts */) > TSDB_MAX_COLUMNS) { if ((superTbls->columnCount + superTbls->tagCount + 1 /* ts */) > TSDB_MAX_COLUMNS) {
errorPrint("%s() LN%d, columns + tags is more than allowed max columns count: %d\n", errorPrint("%s() LN%d, columns + tags is more than allowed max columns count: %d\n",
__func__, __LINE__, TSDB_MAX_COLUMNS); __func__, __LINE__, TSDB_MAX_COLUMNS);
goto PARSE_OVER; goto PARSE_OVER;
} }
ret = true; ret = true;
PARSE_OVER: PARSE_OVER:
return ret; return ret;
} }
static bool getMetaFromInsertJsonFile(cJSON* root) { static bool getMetaFromInsertJsonFile(cJSON* root) {
...@@ -4866,7 +4866,7 @@ static void postFreeResource() { ...@@ -4866,7 +4866,7 @@ static void postFreeResource() {
static int getRowDataFromSample( static int getRowDataFromSample(
char* dataBuf, int64_t maxLen, int64_t timestamp, char* dataBuf, int64_t maxLen, int64_t timestamp,
SSuperTable* superTblInfo, int64_t* sampleUsePos) SSuperTable* superTblInfo, int64_t* sampleUsePos)
{ {
if ((*sampleUsePos) == MAX_SAMPLES_ONCE_FROM_FILE) { if ((*sampleUsePos) == MAX_SAMPLES_ONCE_FROM_FILE) {
/* int ret = readSampleFromCsvFileToMem(superTblInfo); /* int ret = readSampleFromCsvFileToMem(superTblInfo);
...@@ -5118,7 +5118,8 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k) ...@@ -5118,7 +5118,8 @@ static int32_t execInsert(threadInfo *pThreadInfo, uint32_t k)
#if STMT_IFACE_ENABLED == 1 #if STMT_IFACE_ENABLED == 1
case STMT_IFACE: case STMT_IFACE:
debugPrint("%s() LN%d, stmt=%p", __func__, __LINE__, pThreadInfo->stmt); debugPrint("%s() LN%d, stmt=%p",
__func__, __LINE__, pThreadInfo->stmt);
if (0 != taos_stmt_execute(pThreadInfo->stmt)) { if (0 != taos_stmt_execute(pThreadInfo->stmt)) {
errorPrint("%s() LN%d, failied to execute insert statement\n", errorPrint("%s() LN%d, failied to execute insert statement\n",
__func__, __LINE__); __func__, __LINE__);
...@@ -5458,39 +5459,39 @@ static int64_t generateInterlaceDataWithoutStb( ...@@ -5458,39 +5459,39 @@ static int64_t generateInterlaceDataWithoutStb(
int64_t startTime, int64_t startTime,
uint64_t *pRemainderBufLen) uint64_t *pRemainderBufLen)
{ {
assert(buffer); assert(buffer);
char *pstr = buffer; char *pstr = buffer;
int headLen = generateSQLHeadWithoutStb( int headLen = generateSQLHeadWithoutStb(
tableName, dbName, tableName, dbName,
pstr, *pRemainderBufLen); pstr, *pRemainderBufLen);
if (headLen <= 0) { if (headLen <= 0) {
return 0; return 0;
} }
pstr += headLen; pstr += headLen;
*pRemainderBufLen -= headLen; *pRemainderBufLen -= headLen;
int64_t dataLen = 0; int64_t dataLen = 0;
int32_t k = generateDataTailWithoutStb( int32_t k = generateDataTailWithoutStb(
batch, pstr, *pRemainderBufLen, insertRows, 0, batch, pstr, *pRemainderBufLen, insertRows, 0,
startTime, startTime,
&dataLen); &dataLen);
if (k == batch) { if (k == batch) {
pstr += dataLen; pstr += dataLen;
*pRemainderBufLen -= dataLen; *pRemainderBufLen -= dataLen;
} else { } else {
debugPrint("%s() LN%d, generated data tail: %d, not equal batch per table: %u\n", debugPrint("%s() LN%d, generated data tail: %d, not equal batch per table: %u\n",
__func__, __LINE__, k, batch); __func__, __LINE__, k, batch);
pstr -= headLen; pstr -= headLen;
pstr[0] = '\0'; pstr[0] = '\0';
k = 0; k = 0;
} }
return k; return k;
} }
#if STMT_IFACE_ENABLED == 1 #if STMT_IFACE_ENABLED == 1
...@@ -5771,6 +5772,8 @@ static int32_t prepareStbStmtBind( ...@@ -5771,6 +5772,8 @@ static int32_t prepareStbStmtBind(
TAOS_BIND *bind; TAOS_BIND *bind;
if (isColumn) { if (isColumn) {
int cursor = 0;
for (int i = 0; i < stbInfo->columnCount + 1; i ++) { for (int i = 0; i < stbInfo->columnCount + 1; i ++) {
bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * i)); bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * i));
...@@ -5794,7 +5797,6 @@ static int32_t prepareStbStmtBind( ...@@ -5794,7 +5797,6 @@ static int32_t prepareStbStmtBind(
ptr += bind->buffer_length; ptr += bind->buffer_length;
} else { } else {
int cursor = 0;
if (sourceRand) { if (sourceRand) {
if ( -1 == prepareStmtBindArrayByType( if ( -1 == prepareStmtBindArrayByType(
...@@ -5851,6 +5853,7 @@ static int32_t prepareStbStmtBind( ...@@ -5851,6 +5853,7 @@ static int32_t prepareStbStmtBind(
} }
free(bindBuffer);
return 0; return 0;
} }
...@@ -6043,27 +6046,27 @@ static int32_t generateProgressiveDataWithoutStb( ...@@ -6043,27 +6046,27 @@ static int32_t generateProgressiveDataWithoutStb(
uint64_t recordFrom, int64_t startTime, /*int64_t *pSamplePos, */ uint64_t recordFrom, int64_t startTime, /*int64_t *pSamplePos, */
int64_t *pRemainderBufLen) int64_t *pRemainderBufLen)
{ {
assert(buffer != NULL); assert(buffer != NULL);
char *pstr = buffer; char *pstr = buffer;
memset(buffer, 0, *pRemainderBufLen); memset(buffer, 0, *pRemainderBufLen);
int64_t headLen = generateSQLHeadWithoutStb( int64_t headLen = generateSQLHeadWithoutStb(
tableName, pThreadInfo->db_name, tableName, pThreadInfo->db_name,
buffer, *pRemainderBufLen); buffer, *pRemainderBufLen);
if (headLen <= 0) { if (headLen <= 0) {
return 0; return 0;
} }
pstr += headLen; pstr += headLen;
*pRemainderBufLen -= headLen; *pRemainderBufLen -= headLen;
int64_t dataLen; int64_t dataLen;
return generateDataTailWithoutStb( return generateDataTailWithoutStb(
g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, recordFrom, g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, recordFrom,
startTime, startTime,
/*pSamplePos, */&dataLen); /*pSamplePos, */&dataLen);
} }
static void printStatPerThread(threadInfo *pThreadInfo) static void printStatPerThread(threadInfo *pThreadInfo)
...@@ -6552,110 +6555,110 @@ static void* syncWrite(void *sarg) { ...@@ -6552,110 +6555,110 @@ static void* syncWrite(void *sarg) {
} }
static void callBack(void *param, TAOS_RES *res, int code) { static void callBack(void *param, TAOS_RES *res, int code) {
threadInfo* pThreadInfo = (threadInfo*)param; threadInfo* pThreadInfo = (threadInfo*)param;
SSuperTable* superTblInfo = pThreadInfo->superTblInfo; SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
int insert_interval = int insert_interval =
superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
if (insert_interval) { if (insert_interval) {
pThreadInfo->et = taosGetTimestampMs(); pThreadInfo->et = taosGetTimestampMs();
if ((pThreadInfo->et - pThreadInfo->st) < insert_interval) { if ((pThreadInfo->et - pThreadInfo->st) < insert_interval) {
taosMsleep(insert_interval - (pThreadInfo->et - pThreadInfo->st)); // ms taosMsleep(insert_interval - (pThreadInfo->et - pThreadInfo->st)); // ms
} }
}
char *buffer = calloc(1, pThreadInfo->superTblInfo->maxSqlLen);
char data[MAX_DATA_SIZE];
char *pstr = buffer;
pstr += sprintf(pstr, "insert into %s.%s%"PRId64" values",
pThreadInfo->db_name, pThreadInfo->tb_prefix,
pThreadInfo->start_table_from);
// if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) {
if (pThreadInfo->counter >= g_args.num_of_RPR) {
pThreadInfo->start_table_from++;
pThreadInfo->counter = 0;
}
if (pThreadInfo->start_table_from > pThreadInfo->end_table_to) {
tsem_post(&pThreadInfo->lock_sem);
free(buffer);
taos_free_result(res);
return;
}
for (int i = 0; i < g_args.num_of_RPR; i++) {
int rand_num = taosRandom() % 100;
if (0 != pThreadInfo->superTblInfo->disorderRatio
&& rand_num < pThreadInfo->superTblInfo->disorderRatio) {
int64_t d = pThreadInfo->lastTs
- (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1);
generateStbRowData(pThreadInfo->superTblInfo, data, d);
} else {
generateStbRowData(pThreadInfo->superTblInfo,
data, pThreadInfo->lastTs += 1000);
} }
pstr += sprintf(pstr, "%s", data);
pThreadInfo->counter++;
if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) { char *buffer = calloc(1, pThreadInfo->superTblInfo->maxSqlLen);
break; char data[MAX_DATA_SIZE];
char *pstr = buffer;
pstr += sprintf(pstr, "insert into %s.%s%"PRId64" values",
pThreadInfo->db_name, pThreadInfo->tb_prefix,
pThreadInfo->start_table_from);
// if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) {
if (pThreadInfo->counter >= g_args.num_of_RPR) {
pThreadInfo->start_table_from++;
pThreadInfo->counter = 0;
}
if (pThreadInfo->start_table_from > pThreadInfo->end_table_to) {
tsem_post(&pThreadInfo->lock_sem);
free(buffer);
taos_free_result(res);
return;
} }
}
if (insert_interval) { for (int i = 0; i < g_args.num_of_RPR; i++) {
pThreadInfo->st = taosGetTimestampMs(); int rand_num = taosRandom() % 100;
} if (0 != pThreadInfo->superTblInfo->disorderRatio
taos_query_a(pThreadInfo->taos, buffer, callBack, pThreadInfo); && rand_num < pThreadInfo->superTblInfo->disorderRatio) {
free(buffer); int64_t d = pThreadInfo->lastTs
- (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1);
generateStbRowData(pThreadInfo->superTblInfo, data, d);
} else {
generateStbRowData(pThreadInfo->superTblInfo,
data, pThreadInfo->lastTs += 1000);
}
pstr += sprintf(pstr, "%s", data);
pThreadInfo->counter++;
taos_free_result(res); if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) {
break;
}
}
if (insert_interval) {
pThreadInfo->st = taosGetTimestampMs();
}
taos_query_a(pThreadInfo->taos, buffer, callBack, pThreadInfo);
free(buffer);
taos_free_result(res);
} }
static void *asyncWrite(void *sarg) { static void *asyncWrite(void *sarg) {
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
SSuperTable* superTblInfo = pThreadInfo->superTblInfo; SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
setThreadName("asyncWrite"); setThreadName("asyncWrite");
pThreadInfo->st = 0; pThreadInfo->st = 0;
pThreadInfo->et = 0; pThreadInfo->et = 0;
pThreadInfo->lastTs = pThreadInfo->start_time; pThreadInfo->lastTs = pThreadInfo->start_time;
int insert_interval = int insert_interval =
superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
if (insert_interval) { if (insert_interval) {
pThreadInfo->st = taosGetTimestampMs(); pThreadInfo->st = taosGetTimestampMs();
} }
taos_query_a(pThreadInfo->taos, "show databases", callBack, pThreadInfo); taos_query_a(pThreadInfo->taos, "show databases", callBack, pThreadInfo);
tsem_wait(&(pThreadInfo->lock_sem)); tsem_wait(&(pThreadInfo->lock_sem));
return NULL; return NULL;
} }
static int convertHostToServAddr(char *host, uint16_t port, struct sockaddr_in *serv_addr) static int convertHostToServAddr(char *host, uint16_t port, struct sockaddr_in *serv_addr)
{ {
uint16_t rest_port = port + TSDB_PORT_HTTP; uint16_t rest_port = port + TSDB_PORT_HTTP;
struct hostent *server = gethostbyname(host); struct hostent *server = gethostbyname(host);
if ((server == NULL) || (server->h_addr == NULL)) { if ((server == NULL) || (server->h_addr == NULL)) {
errorPrint("%s", "ERROR, no such host"); errorPrint("%s", "ERROR, no such host");
return -1; return -1;
} }
debugPrint("h_name: %s\nh_addr=%p\nh_addretype: %s\nh_length: %d\n", debugPrint("h_name: %s\nh_addr=%p\nh_addretype: %s\nh_length: %d\n",
server->h_name, server->h_name,
server->h_addr, server->h_addr,
(server->h_addrtype == AF_INET)?"ipv4":"ipv6", (server->h_addrtype == AF_INET)?"ipv4":"ipv6",
server->h_length); server->h_length);
memset(serv_addr, 0, sizeof(struct sockaddr_in)); memset(serv_addr, 0, sizeof(struct sockaddr_in));
serv_addr->sin_family = AF_INET; serv_addr->sin_family = AF_INET;
serv_addr->sin_port = htons(rest_port); serv_addr->sin_port = htons(rest_port);
#ifdef WINDOWS #ifdef WINDOWS
serv_addr->sin_addr.s_addr = inet_addr(host); serv_addr->sin_addr.s_addr = inet_addr(host);
#else #else
memcpy(&(serv_addr->sin_addr.s_addr), server->h_addr, server->h_length); memcpy(&(serv_addr->sin_addr.s_addr), server->h_addr, server->h_length);
#endif #endif
return 0; return 0;
} }
static void startMultiThreadInsertData(int threads, char* db_name, static void startMultiThreadInsertData(int threads, char* db_name,
...@@ -6724,14 +6727,17 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -6724,14 +6727,17 @@ static void startMultiThreadInsertData(int threads, char* db_name,
int64_t limit; int64_t limit;
uint64_t offset; uint64_t offset;
if ((NULL != g_args.sqlFile) && (superTblInfo->childTblExists == TBL_NO_EXISTS) && if ((NULL != g_args.sqlFile)
((superTblInfo->childTblOffset != 0) || (superTblInfo->childTblLimit >= 0))) { && (superTblInfo->childTblExists == TBL_NO_EXISTS)
&& ((superTblInfo->childTblOffset != 0)
|| (superTblInfo->childTblLimit >= 0))) {
printf("WARNING: offset and limit will not be used since the child tables not exists!\n"); printf("WARNING: offset and limit will not be used since the child tables not exists!\n");
} }
if (superTblInfo->childTblExists == TBL_ALREADY_EXISTS) { if (superTblInfo->childTblExists == TBL_ALREADY_EXISTS) {
if ((superTblInfo->childTblLimit < 0) if ((superTblInfo->childTblLimit < 0)
|| ((superTblInfo->childTblOffset + superTblInfo->childTblLimit) || ((superTblInfo->childTblOffset
+ superTblInfo->childTblLimit)
> (superTblInfo->childTblCount))) { > (superTblInfo->childTblCount))) {
superTblInfo->childTblLimit = superTblInfo->childTblLimit =
superTblInfo->childTblCount - superTblInfo->childTblOffset; superTblInfo->childTblCount - superTblInfo->childTblOffset;
...@@ -6837,7 +6843,8 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -6837,7 +6843,8 @@ static void startMultiThreadInsertData(int threads, char* db_name,
#if STMT_IFACE_ENABLED == 1 #if STMT_IFACE_ENABLED == 1
if ((g_args.iface == STMT_IFACE) if ((g_args.iface == STMT_IFACE)
|| ((superTblInfo) && (superTblInfo->iface == STMT_IFACE))) { || ((superTblInfo)
&& (superTblInfo->iface == STMT_IFACE))) {
int columnCount; int columnCount;
if (superTblInfo) { if (superTblInfo) {
...@@ -6865,7 +6872,8 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -6865,7 +6872,8 @@ static void startMultiThreadInsertData(int threads, char* db_name,
== superTblInfo->autoCreateTable)) { == superTblInfo->autoCreateTable)) {
pstr += sprintf(pstr, "INSERT INTO ? USING %s TAGS(?", pstr += sprintf(pstr, "INSERT INTO ? USING %s TAGS(?",
superTblInfo->sTblName); superTblInfo->sTblName);
for (int tag = 0; tag < (superTblInfo->tagCount - 1); tag ++ ) { for (int tag = 0; tag < (superTblInfo->tagCount - 1);
tag ++ ) {
pstr += sprintf(pstr, ",?"); pstr += sprintf(pstr, ",?");
} }
pstr += sprintf(pstr, ") VALUES(?"); pstr += sprintf(pstr, ") VALUES(?");
...@@ -7014,157 +7022,157 @@ static void startMultiThreadInsertData(int threads, char* db_name, ...@@ -7014,157 +7022,157 @@ static void startMultiThreadInsertData(int threads, char* db_name,
static void *readTable(void *sarg) { static void *readTable(void *sarg) {
#if 1 #if 1
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
TAOS *taos = pThreadInfo->taos; TAOS *taos = pThreadInfo->taos;
setThreadName("readTable"); setThreadName("readTable");
char command[BUFFER_SIZE] = "\0"; char command[BUFFER_SIZE] = "\0";
uint64_t sTime = pThreadInfo->start_time; uint64_t sTime = pThreadInfo->start_time;
char *tb_prefix = pThreadInfo->tb_prefix; char *tb_prefix = pThreadInfo->tb_prefix;
FILE *fp = fopen(pThreadInfo->filePath, "a"); FILE *fp = fopen(pThreadInfo->filePath, "a");
if (NULL == fp) { if (NULL == fp) {
errorPrint( "fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno)); errorPrint( "fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno));
return NULL;
}
int64_t num_of_DPT;
/* if (pThreadInfo->superTblInfo) {
num_of_DPT = pThreadInfo->superTblInfo->insertRows; // nrecords_per_table;
} else {
*/
num_of_DPT = g_args.num_of_DPT;
// }
int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1;
int64_t totalData = num_of_DPT * num_of_tables;
bool do_aggreFunc = g_Dbs.do_aggreFunc;
int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2;
if (!do_aggreFunc) {
printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n");
}
printf("%"PRId64" records:\n", totalData);
fprintf(fp, "| QFunctions | QRecords | QSpeed(R/s) | QLatency(ms) |\n");
for (int j = 0; j < n; j++) {
double totalT = 0;
uint64_t count = 0;
for (int64_t i = 0; i < num_of_tables; i++) {
sprintf(command, "select %s from %s%"PRId64" where ts>= %" PRIu64,
aggreFunc[j], tb_prefix, i, sTime);
double t = taosGetTimestampMs();
TAOS_RES *pSql = taos_query(taos, command);
int32_t code = taos_errno(pSql);
if (code != 0) {
errorPrint( "Failed to query:%s\n", taos_errstr(pSql));
taos_free_result(pSql);
taos_close(taos);
fclose(fp);
return NULL; return NULL;
} }
while(taos_fetch_row(pSql) != NULL) { int64_t num_of_DPT;
count++; /* if (pThreadInfo->superTblInfo) {
} num_of_DPT = pThreadInfo->superTblInfo->insertRows; // nrecords_per_table;
} else {
*/
num_of_DPT = g_args.num_of_DPT;
// }
int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1;
int64_t totalData = num_of_DPT * num_of_tables;
bool do_aggreFunc = g_Dbs.do_aggreFunc;
int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2;
if (!do_aggreFunc) {
printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n");
}
printf("%"PRId64" records:\n", totalData);
fprintf(fp, "| QFunctions | QRecords | QSpeed(R/s) | QLatency(ms) |\n");
for (int j = 0; j < n; j++) {
double totalT = 0;
uint64_t count = 0;
for (int64_t i = 0; i < num_of_tables; i++) {
sprintf(command, "select %s from %s%"PRId64" where ts>= %" PRIu64,
aggreFunc[j], tb_prefix, i, sTime);
double t = taosGetTimestampMs();
TAOS_RES *pSql = taos_query(taos, command);
int32_t code = taos_errno(pSql);
if (code != 0) {
errorPrint( "Failed to query:%s\n", taos_errstr(pSql));
taos_free_result(pSql);
taos_close(taos);
fclose(fp);
return NULL;
}
t = taosGetTimestampMs() - t; while(taos_fetch_row(pSql) != NULL) {
totalT += t; count++;
}
taos_free_result(pSql); t = taosGetTimestampMs() - t;
} totalT += t;
taos_free_result(pSql);
}
fprintf(fp, "|%10s | %"PRId64" | %12.2f | %10.2f |\n", fprintf(fp, "|%10s | %"PRId64" | %12.2f | %10.2f |\n",
aggreFunc[j][0] == '*' ? " * " : aggreFunc[j], totalData, aggreFunc[j][0] == '*' ? " * " : aggreFunc[j], totalData,
(double)(num_of_tables * num_of_DPT) / totalT, totalT * 1000); (double)(num_of_tables * num_of_DPT) / totalT, totalT * 1000);
printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT * 1000); printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT * 1000);
} }
fprintf(fp, "\n"); fprintf(fp, "\n");
fclose(fp); fclose(fp);
#endif #endif
return NULL; return NULL;
} }
static void *readMetric(void *sarg) { static void *readMetric(void *sarg) {
#if 1 #if 1
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
TAOS *taos = pThreadInfo->taos; TAOS *taos = pThreadInfo->taos;
setThreadName("readMetric"); setThreadName("readMetric");
char command[BUFFER_SIZE] = "\0"; char command[BUFFER_SIZE] = "\0";
FILE *fp = fopen(pThreadInfo->filePath, "a"); FILE *fp = fopen(pThreadInfo->filePath, "a");
if (NULL == fp) { if (NULL == fp) {
printf("fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno)); printf("fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno));
return NULL; return NULL;
} }
int64_t num_of_DPT = pThreadInfo->superTblInfo->insertRows; int64_t num_of_DPT = pThreadInfo->superTblInfo->insertRows;
int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1;
int64_t totalData = num_of_DPT * num_of_tables; int64_t totalData = num_of_DPT * num_of_tables;
bool do_aggreFunc = g_Dbs.do_aggreFunc; bool do_aggreFunc = g_Dbs.do_aggreFunc;
int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2; int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2;
if (!do_aggreFunc) { if (!do_aggreFunc) {
printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n"); printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n");
} }
printf("%"PRId64" records:\n", totalData); printf("%"PRId64" records:\n", totalData);
fprintf(fp, "Querying On %"PRId64" records:\n", totalData); fprintf(fp, "Querying On %"PRId64" records:\n", totalData);
for (int j = 0; j < n; j++) { for (int j = 0; j < n; j++) {
char condition[COND_BUF_LEN] = "\0"; char condition[COND_BUF_LEN] = "\0";
char tempS[64] = "\0"; char tempS[64] = "\0";
int64_t m = 10 < num_of_tables ? 10 : num_of_tables; int64_t m = 10 < num_of_tables ? 10 : num_of_tables;
for (int64_t i = 1; i <= m; i++) { for (int64_t i = 1; i <= m; i++) {
if (i == 1) { if (i == 1) {
sprintf(tempS, "t1 = %"PRId64"", i); sprintf(tempS, "t1 = %"PRId64"", i);
} else { } else {
sprintf(tempS, " or t1 = %"PRId64" ", i); sprintf(tempS, " or t1 = %"PRId64" ", i);
} }
strncat(condition, tempS, COND_BUF_LEN - 1); strncat(condition, tempS, COND_BUF_LEN - 1);
sprintf(command, "select %s from meters where %s", aggreFunc[j], condition); sprintf(command, "select %s from meters where %s", aggreFunc[j], condition);
printf("Where condition: %s\n", condition); printf("Where condition: %s\n", condition);
fprintf(fp, "%s\n", command); fprintf(fp, "%s\n", command);
double t = taosGetTimestampMs(); double t = taosGetTimestampMs();
TAOS_RES *pSql = taos_query(taos, command); TAOS_RES *pSql = taos_query(taos, command);
int32_t code = taos_errno(pSql); int32_t code = taos_errno(pSql);
if (code != 0) { if (code != 0) {
errorPrint( "Failed to query:%s\n", taos_errstr(pSql)); errorPrint( "Failed to query:%s\n", taos_errstr(pSql));
taos_free_result(pSql); taos_free_result(pSql);
taos_close(taos); taos_close(taos);
fclose(fp); fclose(fp);
return NULL; return NULL;
} }
int count = 0; int count = 0;
while(taos_fetch_row(pSql) != NULL) { while(taos_fetch_row(pSql) != NULL) {
count++; count++;
} }
t = taosGetTimestampMs() - t; t = taosGetTimestampMs() - t;
fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n", fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n",
num_of_tables * num_of_DPT / (t * 1000.0), t); num_of_tables * num_of_DPT / (t * 1000.0), t);
printf("select %10s took %.6f second(s)\n\n", aggreFunc[j], t * 1000.0); printf("select %10s took %.6f second(s)\n\n", aggreFunc[j], t * 1000.0);
taos_free_result(pSql); taos_free_result(pSql);
}
fprintf(fp, "\n");
} }
fprintf(fp, "\n"); fclose(fp);
}
fclose(fp);
#endif #endif
return NULL; return NULL;
} }
static void prompt() static void prompt()
{ {
if (!g_args.answer_yes) { if (!g_args.answer_yes) {
printf(" Press enter key to continue or Ctrl-C to stop\n\n"); printf(" Press enter key to continue or Ctrl-C to stop\n\n");
(void)getchar(); (void)getchar();
} }
} }
static int insertTestProcess() { static int insertTestProcess() {
...@@ -7264,369 +7272,369 @@ static int insertTestProcess() { ...@@ -7264,369 +7272,369 @@ static int insertTestProcess() {
} }
static void *specifiedTableQuery(void *sarg) { static void *specifiedTableQuery(void *sarg) {
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
setThreadName("specTableQuery"); setThreadName("specTableQuery");
if (pThreadInfo->taos == NULL) { if (pThreadInfo->taos == NULL) {
TAOS * taos = NULL; TAOS * taos = NULL;
taos = taos_connect(g_queryInfo.host, taos = taos_connect(g_queryInfo.host,
g_queryInfo.user, g_queryInfo.user,
g_queryInfo.password, g_queryInfo.password,
NULL, NULL,
g_queryInfo.port); g_queryInfo.port);
if (taos == NULL) { if (taos == NULL) {
errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
pThreadInfo->threadID, taos_errstr(NULL)); pThreadInfo->threadID, taos_errstr(NULL));
return NULL; return NULL;
} else { } else {
pThreadInfo->taos = taos; pThreadInfo->taos = taos;
}
} }
}
char sqlStr[TSDB_DB_NAME_LEN + 5]; char sqlStr[TSDB_DB_NAME_LEN + 5];
sprintf(sqlStr, "use %s", g_queryInfo.dbName); sprintf(sqlStr, "use %s", g_queryInfo.dbName);
if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) { if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
taos_close(pThreadInfo->taos); taos_close(pThreadInfo->taos);
errorPrint( "use database %s failed!\n\n", errorPrint( "use database %s failed!\n\n",
g_queryInfo.dbName); g_queryInfo.dbName);
return NULL; return NULL;
} }
uint64_t st = 0; uint64_t st = 0;
uint64_t et = 0; uint64_t et = 0;
uint64_t queryTimes = g_queryInfo.specifiedQueryInfo.queryTimes; uint64_t queryTimes = g_queryInfo.specifiedQueryInfo.queryTimes;
uint64_t totalQueried = 0; uint64_t totalQueried = 0;
uint64_t lastPrintTime = taosGetTimestampMs(); uint64_t lastPrintTime = taosGetTimestampMs();
uint64_t startTs = taosGetTimestampMs(); uint64_t startTs = taosGetTimestampMs();
if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') { if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') {
sprintf(pThreadInfo->filePath, "%s-%d", sprintf(pThreadInfo->filePath, "%s-%d",
g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
pThreadInfo->threadID); pThreadInfo->threadID);
}
while(queryTimes --) {
if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) <
(int64_t)g_queryInfo.specifiedQueryInfo.queryInterval) {
taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval - (et - st)); // ms
} }
st = taosGetTimestampMs(); while(queryTimes --) {
if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) <
(int64_t)g_queryInfo.specifiedQueryInfo.queryInterval) {
taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval - (et - st)); // ms
}
st = taosGetTimestampMs();
selectAndGetResult(pThreadInfo, selectAndGetResult(pThreadInfo,
g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq]); g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq]);
et = taosGetTimestampMs(); et = taosGetTimestampMs();
printf("=thread[%"PRId64"] use %s complete one sql, Spent %10.3f s\n", printf("=thread[%"PRId64"] use %s complete one sql, Spent %10.3f s\n",
taosGetSelfPthreadId(), g_queryInfo.queryMode, (et - st)/1000.0); taosGetSelfPthreadId(), g_queryInfo.queryMode, (et - st)/1000.0);
totalQueried ++; totalQueried ++;
g_queryInfo.specifiedQueryInfo.totalQueried ++; g_queryInfo.specifiedQueryInfo.totalQueried ++;
uint64_t currentPrintTime = taosGetTimestampMs(); uint64_t currentPrintTime = taosGetTimestampMs();
uint64_t endTs = taosGetTimestampMs(); uint64_t endTs = taosGetTimestampMs();
if (currentPrintTime - lastPrintTime > 30*1000) { if (currentPrintTime - lastPrintTime > 30*1000) {
debugPrint("%s() LN%d, endTs=%"PRIu64"ms, startTs=%"PRIu64"ms\n", debugPrint("%s() LN%d, endTs=%"PRIu64"ms, startTs=%"PRIu64"ms\n",
__func__, __LINE__, endTs, startTs); __func__, __LINE__, endTs, startTs);
printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.6f\n", printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.6f\n",
pThreadInfo->threadID, pThreadInfo->threadID,
totalQueried, totalQueried,
(double)(totalQueried/((endTs-startTs)/1000.0))); (double)(totalQueried/((endTs-startTs)/1000.0)));
lastPrintTime = currentPrintTime; lastPrintTime = currentPrintTime;
}
} }
} return NULL;
return NULL;
} }
static void replaceChildTblName(char* inSql, char* outSql, int tblIndex) { static void replaceChildTblName(char* inSql, char* outSql, int tblIndex) {
char sourceString[32] = "xxxx"; char sourceString[32] = "xxxx";
char subTblName[MAX_TB_NAME_SIZE*3]; char subTblName[MAX_TB_NAME_SIZE*3];
sprintf(subTblName, "%s.%s", sprintf(subTblName, "%s.%s",
g_queryInfo.dbName, g_queryInfo.dbName,
g_queryInfo.superQueryInfo.childTblName + tblIndex*TSDB_TABLE_NAME_LEN); g_queryInfo.superQueryInfo.childTblName + tblIndex*TSDB_TABLE_NAME_LEN);
//printf("inSql: %s\n", inSql); //printf("inSql: %s\n", inSql);
char* pos = strstr(inSql, sourceString); char* pos = strstr(inSql, sourceString);
if (0 == pos) { if (0 == pos) {
return; return;
} }
tstrncpy(outSql, inSql, pos - inSql + 1); tstrncpy(outSql, inSql, pos - inSql + 1);
//printf("1: %s\n", outSql); //printf("1: %s\n", outSql);
strncat(outSql, subTblName, MAX_QUERY_SQL_LENGTH - 1); strncat(outSql, subTblName, MAX_QUERY_SQL_LENGTH - 1);
//printf("2: %s\n", outSql); //printf("2: %s\n", outSql);
strncat(outSql, pos+strlen(sourceString), MAX_QUERY_SQL_LENGTH - 1); strncat(outSql, pos+strlen(sourceString), MAX_QUERY_SQL_LENGTH - 1);
//printf("3: %s\n", outSql); //printf("3: %s\n", outSql);
} }
static void *superTableQuery(void *sarg) { static void *superTableQuery(void *sarg) {
char sqlstr[MAX_QUERY_SQL_LENGTH]; char sqlstr[MAX_QUERY_SQL_LENGTH];
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
setThreadName("superTableQuery"); setThreadName("superTableQuery");
if (pThreadInfo->taos == NULL) { if (pThreadInfo->taos == NULL) {
TAOS * taos = NULL; TAOS * taos = NULL;
taos = taos_connect(g_queryInfo.host, taos = taos_connect(g_queryInfo.host,
g_queryInfo.user, g_queryInfo.user,
g_queryInfo.password, g_queryInfo.password,
NULL, NULL,
g_queryInfo.port); g_queryInfo.port);
if (taos == NULL) { if (taos == NULL) {
errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
pThreadInfo->threadID, taos_errstr(NULL)); pThreadInfo->threadID, taos_errstr(NULL));
return NULL; return NULL;
} else { } else {
pThreadInfo->taos = taos; pThreadInfo->taos = taos;
}
} }
}
uint64_t st = 0;
uint64_t et = (int64_t)g_queryInfo.superQueryInfo.queryInterval;
uint64_t queryTimes = g_queryInfo.superQueryInfo.queryTimes; uint64_t st = 0;
uint64_t totalQueried = 0; uint64_t et = (int64_t)g_queryInfo.superQueryInfo.queryInterval;
uint64_t startTs = taosGetTimestampMs();
uint64_t lastPrintTime = taosGetTimestampMs(); uint64_t queryTimes = g_queryInfo.superQueryInfo.queryTimes;
while(queryTimes --) { uint64_t totalQueried = 0;
if (g_queryInfo.superQueryInfo.queryInterval uint64_t startTs = taosGetTimestampMs();
&& (et - st) < (int64_t)g_queryInfo.superQueryInfo.queryInterval) {
taosMsleep(g_queryInfo.superQueryInfo.queryInterval - (et - st)); // ms
//printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to);
}
st = taosGetTimestampMs(); uint64_t lastPrintTime = taosGetTimestampMs();
for (int i = pThreadInfo->start_table_from; i <= pThreadInfo->end_table_to; i++) { while(queryTimes --) {
for (int j = 0; j < g_queryInfo.superQueryInfo.sqlCount; j++) { if (g_queryInfo.superQueryInfo.queryInterval
memset(sqlstr,0,sizeof(sqlstr)); && (et - st) < (int64_t)g_queryInfo.superQueryInfo.queryInterval) {
replaceChildTblName(g_queryInfo.superQueryInfo.sql[j], sqlstr, i); taosMsleep(g_queryInfo.superQueryInfo.queryInterval - (et - st)); // ms
if (g_queryInfo.superQueryInfo.result[j][0] != '\0') { //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to);
sprintf(pThreadInfo->filePath, "%s-%d", }
g_queryInfo.superQueryInfo.result[j],
pThreadInfo->threadID); st = taosGetTimestampMs();
} for (int i = pThreadInfo->start_table_from; i <= pThreadInfo->end_table_to; i++) {
selectAndGetResult(pThreadInfo, sqlstr); for (int j = 0; j < g_queryInfo.superQueryInfo.sqlCount; j++) {
memset(sqlstr,0,sizeof(sqlstr));
replaceChildTblName(g_queryInfo.superQueryInfo.sql[j], sqlstr, i);
if (g_queryInfo.superQueryInfo.result[j][0] != '\0') {
sprintf(pThreadInfo->filePath, "%s-%d",
g_queryInfo.superQueryInfo.result[j],
pThreadInfo->threadID);
}
selectAndGetResult(pThreadInfo, sqlstr);
totalQueried++; totalQueried++;
g_queryInfo.superQueryInfo.totalQueried ++; g_queryInfo.superQueryInfo.totalQueried ++;
int64_t currentPrintTime = taosGetTimestampMs(); int64_t currentPrintTime = taosGetTimestampMs();
int64_t endTs = taosGetTimestampMs(); int64_t endTs = taosGetTimestampMs();
if (currentPrintTime - lastPrintTime > 30*1000) { if (currentPrintTime - lastPrintTime > 30*1000) {
printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.3f\n", printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.3f\n",
pThreadInfo->threadID, pThreadInfo->threadID,
totalQueried, totalQueried,
(double)(totalQueried/((endTs-startTs)/1000.0))); (double)(totalQueried/((endTs-startTs)/1000.0)));
lastPrintTime = currentPrintTime; lastPrintTime = currentPrintTime;
}
}
} }
} et = taosGetTimestampMs();
printf("####thread[%"PRId64"] complete all sqls to allocate all sub-tables[%"PRIu64" - %"PRIu64"] once queries duration:%.4fs\n\n",
taosGetSelfPthreadId(),
pThreadInfo->start_table_from,
pThreadInfo->end_table_to,
(double)(et - st)/1000.0);
} }
et = taosGetTimestampMs();
printf("####thread[%"PRId64"] complete all sqls to allocate all sub-tables[%"PRIu64" - %"PRIu64"] once queries duration:%.4fs\n\n",
taosGetSelfPthreadId(),
pThreadInfo->start_table_from,
pThreadInfo->end_table_to,
(double)(et - st)/1000.0);
}
return NULL; return NULL;
} }
static int queryTestProcess() { static int queryTestProcess() {
setupForAnsiEscape(); setupForAnsiEscape();
printfQueryMeta(); printfQueryMeta();
resetAfterAnsiEscape(); resetAfterAnsiEscape();
TAOS * taos = NULL;
taos = taos_connect(g_queryInfo.host,
g_queryInfo.user,
g_queryInfo.password,
NULL,
g_queryInfo.port);
if (taos == NULL) {
errorPrint( "Failed to connect to TDengine, reason:%s\n",
taos_errstr(NULL));
exit(-1);
}
if (0 != g_queryInfo.superQueryInfo.sqlCount) {
getAllChildNameOfSuperTable(taos,
g_queryInfo.dbName,
g_queryInfo.superQueryInfo.sTblName,
&g_queryInfo.superQueryInfo.childTblName,
&g_queryInfo.superQueryInfo.childTblCount);
}
prompt(); TAOS * taos = NULL;
taos = taos_connect(g_queryInfo.host,
g_queryInfo.user,
g_queryInfo.password,
NULL,
g_queryInfo.port);
if (taos == NULL) {
errorPrint( "Failed to connect to TDengine, reason:%s\n",
taos_errstr(NULL));
exit(-1);
}
if (g_args.debug_print || g_args.verbose_print) { if (0 != g_queryInfo.superQueryInfo.sqlCount) {
printfQuerySystemInfo(taos); getAllChildNameOfSuperTable(taos,
} g_queryInfo.dbName,
g_queryInfo.superQueryInfo.sTblName,
&g_queryInfo.superQueryInfo.childTblName,
&g_queryInfo.superQueryInfo.childTblCount);
}
if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) { prompt();
if (convertHostToServAddr(
g_queryInfo.host, g_queryInfo.port, &g_queryInfo.serv_addr) != 0)
exit(-1);
}
pthread_t *pids = NULL; if (g_args.debug_print || g_args.verbose_print) {
threadInfo *infos = NULL; printfQuerySystemInfo(taos);
//==== create sub threads for query from specify table }
int nConcurrent = g_queryInfo.specifiedQueryInfo.concurrent;
uint64_t nSqlCount = g_queryInfo.specifiedQueryInfo.sqlCount;
uint64_t startTs = taosGetTimestampMs(); if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) {
if (convertHostToServAddr(
g_queryInfo.host, g_queryInfo.port, &g_queryInfo.serv_addr) != 0)
exit(-1);
}
if ((nSqlCount > 0) && (nConcurrent > 0)) { pthread_t *pids = NULL;
threadInfo *infos = NULL;
//==== create sub threads for query from specify table
int nConcurrent = g_queryInfo.specifiedQueryInfo.concurrent;
uint64_t nSqlCount = g_queryInfo.specifiedQueryInfo.sqlCount;
pids = calloc(1, nConcurrent * nSqlCount * sizeof(pthread_t)); uint64_t startTs = taosGetTimestampMs();
infos = calloc(1, nConcurrent * nSqlCount * sizeof(threadInfo));
if ((NULL == pids) || (NULL == infos)) { if ((nSqlCount > 0) && (nConcurrent > 0)) {
taos_close(taos);
ERROR_EXIT("memory allocation failed for create threads\n");
}
for (uint64_t i = 0; i < nSqlCount; i++) { pids = calloc(1, nConcurrent * nSqlCount * sizeof(pthread_t));
for (int j = 0; j < nConcurrent; j++) { infos = calloc(1, nConcurrent * nSqlCount * sizeof(threadInfo));
uint64_t seq = i * nConcurrent + j;
threadInfo *pThreadInfo = infos + seq;
pThreadInfo->threadID = seq;
pThreadInfo->querySeq = i;
if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { if ((NULL == pids) || (NULL == infos)) {
taos_close(taos);
ERROR_EXIT("memory allocation failed for create threads\n");
}
char sqlStr[MAX_TB_NAME_SIZE*2]; for (uint64_t i = 0; i < nSqlCount; i++) {
sprintf(sqlStr, "use %s", g_queryInfo.dbName); for (int j = 0; j < nConcurrent; j++) {
if (0 != queryDbExec(taos, sqlStr, NO_INSERT_TYPE, false)) { uint64_t seq = i * nConcurrent + j;
taos_close(taos); threadInfo *pThreadInfo = infos + seq;
free(infos); pThreadInfo->threadID = seq;
free(pids); pThreadInfo->querySeq = i;
errorPrint( "use database %s failed!\n\n",
g_queryInfo.dbName); if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) {
return -1;
char sqlStr[MAX_TB_NAME_SIZE*2];
sprintf(sqlStr, "use %s", g_queryInfo.dbName);
if (0 != queryDbExec(taos, sqlStr, NO_INSERT_TYPE, false)) {
taos_close(taos);
free(infos);
free(pids);
errorPrint( "use database %s failed!\n\n",
g_queryInfo.dbName);
return -1;
}
} }
}
pThreadInfo->taos = NULL;// TODO: workaround to use separate taos connection; pThreadInfo->taos = NULL;// TODO: workaround to use separate taos connection;
pthread_create(pids + seq, NULL, specifiedTableQuery, pthread_create(pids + seq, NULL, specifiedTableQuery,
pThreadInfo); pThreadInfo);
}
} }
} else {
g_queryInfo.specifiedQueryInfo.concurrent = 0;
} }
} else {
g_queryInfo.specifiedQueryInfo.concurrent = 0;
}
taos_close(taos); taos_close(taos);
pthread_t *pidsOfSub = NULL; pthread_t *pidsOfSub = NULL;
threadInfo *infosOfSub = NULL; threadInfo *infosOfSub = NULL;
//==== create sub threads for query from all sub table of the super table //==== create sub threads for query from all sub table of the super table
if ((g_queryInfo.superQueryInfo.sqlCount > 0) if ((g_queryInfo.superQueryInfo.sqlCount > 0)
&& (g_queryInfo.superQueryInfo.threadCnt > 0)) { && (g_queryInfo.superQueryInfo.threadCnt > 0)) {
pidsOfSub = calloc(1, g_queryInfo.superQueryInfo.threadCnt * sizeof(pthread_t)); pidsOfSub = calloc(1, g_queryInfo.superQueryInfo.threadCnt * sizeof(pthread_t));
infosOfSub = calloc(1, g_queryInfo.superQueryInfo.threadCnt * sizeof(threadInfo)); infosOfSub = calloc(1, g_queryInfo.superQueryInfo.threadCnt * sizeof(threadInfo));
if ((NULL == pidsOfSub) || (NULL == infosOfSub)) { if ((NULL == pidsOfSub) || (NULL == infosOfSub)) {
free(infos); free(infos);
free(pids); free(pids);
ERROR_EXIT("memory allocation failed for create threads\n"); ERROR_EXIT("memory allocation failed for create threads\n");
} }
int64_t ntables = g_queryInfo.superQueryInfo.childTblCount; int64_t ntables = g_queryInfo.superQueryInfo.childTblCount;
int threads = g_queryInfo.superQueryInfo.threadCnt; int threads = g_queryInfo.superQueryInfo.threadCnt;
int64_t a = ntables / threads; int64_t a = ntables / threads;
if (a < 1) { if (a < 1) {
threads = ntables; threads = ntables;
a = 1; a = 1;
} }
int64_t b = 0; int64_t b = 0;
if (threads != 0) { if (threads != 0) {
b = ntables % threads; b = ntables % threads;
} }
uint64_t tableFrom = 0; uint64_t tableFrom = 0;
for (int i = 0; i < threads; i++) { for (int i = 0; i < threads; i++) {
threadInfo *pThreadInfo = infosOfSub + i; threadInfo *pThreadInfo = infosOfSub + i;
pThreadInfo->threadID = i; pThreadInfo->threadID = i;
pThreadInfo->start_table_from = tableFrom; pThreadInfo->start_table_from = tableFrom;
pThreadInfo->ntables = i<b?a+1:a; pThreadInfo->ntables = i<b?a+1:a;
pThreadInfo->end_table_to = i < b ? tableFrom + a : tableFrom + a - 1; pThreadInfo->end_table_to = i < b ? tableFrom + a : tableFrom + a - 1;
tableFrom = pThreadInfo->end_table_to + 1; tableFrom = pThreadInfo->end_table_to + 1;
pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection;
pthread_create(pidsOfSub + i, NULL, superTableQuery, pThreadInfo); pthread_create(pidsOfSub + i, NULL, superTableQuery, pThreadInfo);
} }
g_queryInfo.superQueryInfo.threadCnt = threads; g_queryInfo.superQueryInfo.threadCnt = threads;
} else { } else {
g_queryInfo.superQueryInfo.threadCnt = 0; g_queryInfo.superQueryInfo.threadCnt = 0;
} }
if ((nSqlCount > 0) && (nConcurrent > 0)) { if ((nSqlCount > 0) && (nConcurrent > 0)) {
for (int i = 0; i < nConcurrent; i++) { for (int i = 0; i < nConcurrent; i++) {
for (int j = 0; j < nSqlCount; j++) { for (int j = 0; j < nSqlCount; j++) {
pthread_join(pids[i * nSqlCount + j], NULL); pthread_join(pids[i * nSqlCount + j], NULL);
} }
}
} }
}
tmfree((char*)pids); tmfree((char*)pids);
tmfree((char*)infos); tmfree((char*)infos);
for (int i = 0; i < g_queryInfo.superQueryInfo.threadCnt; i++) { for (int i = 0; i < g_queryInfo.superQueryInfo.threadCnt; i++) {
pthread_join(pidsOfSub[i], NULL); pthread_join(pidsOfSub[i], NULL);
} }
tmfree((char*)pidsOfSub); tmfree((char*)pidsOfSub);
tmfree((char*)infosOfSub); tmfree((char*)infosOfSub);
// taos_close(taos);// TODO: workaround to use separate taos connection; // taos_close(taos);// TODO: workaround to use separate taos connection;
uint64_t endTs = taosGetTimestampMs(); uint64_t endTs = taosGetTimestampMs();
uint64_t totalQueried = g_queryInfo.specifiedQueryInfo.totalQueried + uint64_t totalQueried = g_queryInfo.specifiedQueryInfo.totalQueried +
g_queryInfo.superQueryInfo.totalQueried; g_queryInfo.superQueryInfo.totalQueried;
fprintf(stderr, "==== completed total queries: %"PRIu64", the QPS of all threads: %10.3f====\n", fprintf(stderr, "==== completed total queries: %"PRIu64", the QPS of all threads: %10.3f====\n",
totalQueried, totalQueried,
(double)(totalQueried/((endTs-startTs)/1000.0))); (double)(totalQueried/((endTs-startTs)/1000.0)));
return 0; return 0;
} }
static void stable_sub_callback( static void stable_sub_callback(
TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
if (res == NULL || taos_errno(res) != 0) { if (res == NULL || taos_errno(res) != 0) {
errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n", errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n",
__func__, __LINE__, code, taos_errstr(res)); __func__, __LINE__, code, taos_errstr(res));
return; return;
} }
if (param) if (param)
fetchResult(res, (threadInfo *)param); fetchResult(res, (threadInfo *)param);
// tao_unscribe() will free result. // tao_unscribe() will free result.
} }
static void specified_sub_callback( static void specified_sub_callback(
TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) { TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
if (res == NULL || taos_errno(res) != 0) { if (res == NULL || taos_errno(res) != 0) {
errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n", errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n",
__func__, __LINE__, code, taos_errstr(res)); __func__, __LINE__, code, taos_errstr(res));
return; return;
} }
if (param) if (param)
fetchResult(res, (threadInfo *)param); fetchResult(res, (threadInfo *)param);
// tao_unscribe() will free result. // tao_unscribe() will free result.
} }
static TAOS_SUB* subscribeImpl( static TAOS_SUB* subscribeImpl(
...@@ -7634,35 +7642,35 @@ static TAOS_SUB* subscribeImpl( ...@@ -7634,35 +7642,35 @@ static TAOS_SUB* subscribeImpl(
threadInfo *pThreadInfo, threadInfo *pThreadInfo,
char *sql, char* topic, bool restart, uint64_t interval) char *sql, char* topic, bool restart, uint64_t interval)
{ {
TAOS_SUB* tsub = NULL; TAOS_SUB* tsub = NULL;
if ((SPECIFIED_CLASS == class) if ((SPECIFIED_CLASS == class)
&& (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode)) { && (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode)) {
tsub = taos_subscribe( tsub = taos_subscribe(
pThreadInfo->taos, pThreadInfo->taos,
restart, restart,
topic, sql, specified_sub_callback, (void*)pThreadInfo, topic, sql, specified_sub_callback, (void*)pThreadInfo,
g_queryInfo.specifiedQueryInfo.subscribeInterval); g_queryInfo.specifiedQueryInfo.subscribeInterval);
} else if ((STABLE_CLASS == class) } else if ((STABLE_CLASS == class)
&& (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode)) { && (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode)) {
tsub = taos_subscribe( tsub = taos_subscribe(
pThreadInfo->taos, pThreadInfo->taos,
restart, restart,
topic, sql, stable_sub_callback, (void*)pThreadInfo, topic, sql, stable_sub_callback, (void*)pThreadInfo,
g_queryInfo.superQueryInfo.subscribeInterval); g_queryInfo.superQueryInfo.subscribeInterval);
} else { } else {
tsub = taos_subscribe( tsub = taos_subscribe(
pThreadInfo->taos, pThreadInfo->taos,
restart, restart,
topic, sql, NULL, NULL, interval); topic, sql, NULL, NULL, interval);
} }
if (tsub == NULL) { if (tsub == NULL) {
errorPrint("failed to create subscription. topic:%s, sql:%s\n", topic, sql); errorPrint("failed to create subscription. topic:%s, sql:%s\n", topic, sql);
return NULL; return NULL;
} }
return tsub; return tsub;
} }
static void *superSubscribe(void *sarg) { static void *superSubscribe(void *sarg) {
...@@ -7816,291 +7824,291 @@ static void *superSubscribe(void *sarg) { ...@@ -7816,291 +7824,291 @@ static void *superSubscribe(void *sarg) {
} }
static void *specifiedSubscribe(void *sarg) { static void *specifiedSubscribe(void *sarg) {
threadInfo *pThreadInfo = (threadInfo *)sarg; threadInfo *pThreadInfo = (threadInfo *)sarg;
// TAOS_SUB* tsub = NULL; // TAOS_SUB* tsub = NULL;
setThreadName("specSub"); setThreadName("specSub");
if (pThreadInfo->taos == NULL) {
pThreadInfo->taos = taos_connect(g_queryInfo.host,
g_queryInfo.user,
g_queryInfo.password,
g_queryInfo.dbName,
g_queryInfo.port);
if (pThreadInfo->taos == NULL) { if (pThreadInfo->taos == NULL) {
errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", pThreadInfo->taos = taos_connect(g_queryInfo.host,
pThreadInfo->threadID, taos_errstr(NULL)); g_queryInfo.user,
return NULL; g_queryInfo.password,
g_queryInfo.dbName,
g_queryInfo.port);
if (pThreadInfo->taos == NULL) {
errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
pThreadInfo->threadID, taos_errstr(NULL));
return NULL;
}
} }
}
char sqlStr[MAX_TB_NAME_SIZE*2]; char sqlStr[MAX_TB_NAME_SIZE*2];
sprintf(sqlStr, "use %s", g_queryInfo.dbName); sprintf(sqlStr, "use %s", g_queryInfo.dbName);
if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) { if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
taos_close(pThreadInfo->taos); taos_close(pThreadInfo->taos);
return NULL; return NULL;
} }
sprintf(g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID], sprintf(g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID],
"taosdemo-subscribe-%"PRIu64"-%d", "taosdemo-subscribe-%"PRIu64"-%d",
pThreadInfo->querySeq, pThreadInfo->querySeq,
pThreadInfo->threadID); pThreadInfo->threadID);
if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') { if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') {
sprintf(pThreadInfo->filePath, "%s-%d", sprintf(pThreadInfo->filePath, "%s-%d",
g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq], g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
pThreadInfo->threadID); pThreadInfo->threadID);
} }
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] = subscribeImpl( g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] = subscribeImpl(
SPECIFIED_CLASS, pThreadInfo, SPECIFIED_CLASS, pThreadInfo,
g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq], g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID], g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID],
g_queryInfo.specifiedQueryInfo.subscribeRestart, g_queryInfo.specifiedQueryInfo.subscribeRestart,
g_queryInfo.specifiedQueryInfo.subscribeInterval); g_queryInfo.specifiedQueryInfo.subscribeInterval);
if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) { if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) {
taos_close(pThreadInfo->taos); taos_close(pThreadInfo->taos);
return NULL; return NULL;
} }
// start loop to consume result // start loop to consume result
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
while((g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq] == -1)
|| (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] <
g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq])) {
printf("consumed[%d]: %d, endAfterConsum[%"PRId64"]: %d\n",
pThreadInfo->threadID,
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID],
pThreadInfo->querySeq,
g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq]);
if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) {
continue;
}
g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID] = taos_consume(
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]);
if (g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]) {
if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0]
!= 0) {
sprintf(pThreadInfo->filePath, "%s-%d",
g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
pThreadInfo->threadID);
}
fetchResult(
g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID],
pThreadInfo);
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] ++;
if ((g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq] != -1)
&& (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] >=
g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq])) {
printf("keepProgress:%d, resub specified query: %"PRIu64"\n",
g_queryInfo.specifiedQueryInfo.subscribeKeepProgress,
pThreadInfo->querySeq);
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
taos_unsubscribe(g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID],
g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] =
subscribeImpl(
SPECIFIED_CLASS,
pThreadInfo,
g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID],
g_queryInfo.specifiedQueryInfo.subscribeRestart,
g_queryInfo.specifiedQueryInfo.subscribeInterval);
if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) {
taos_close(pThreadInfo->taos);
return NULL;
}
}
}
}
taos_free_result(g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]);
taos_close(pThreadInfo->taos);
return NULL; g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
while((g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq] == -1)
|| (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] <
g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq])) {
printf("consumed[%d]: %d, endAfterConsum[%"PRId64"]: %d\n",
pThreadInfo->threadID,
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID],
pThreadInfo->querySeq,
g_queryInfo.specifiedQueryInfo.endAfterConsume[pThreadInfo->querySeq]);
if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) {
continue;
}
g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID] = taos_consume(
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]);
if (g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]) {
if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0]
!= 0) {
sprintf(pThreadInfo->filePath, "%s-%d",
g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
pThreadInfo->threadID);
}
fetchResult(
g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID],
pThreadInfo);
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] ++;
if ((g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq] != -1)
&& (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] >=
g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq])) {
printf("keepProgress:%d, resub specified query: %"PRIu64"\n",
g_queryInfo.specifiedQueryInfo.subscribeKeepProgress,
pThreadInfo->querySeq);
g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
taos_unsubscribe(g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID],
g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] =
subscribeImpl(
SPECIFIED_CLASS,
pThreadInfo,
g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID],
g_queryInfo.specifiedQueryInfo.subscribeRestart,
g_queryInfo.specifiedQueryInfo.subscribeInterval);
if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) {
taos_close(pThreadInfo->taos);
return NULL;
}
}
}
}
taos_free_result(g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]);
taos_close(pThreadInfo->taos);
return NULL;
} }
static int subscribeTestProcess() { static int subscribeTestProcess() {
setupForAnsiEscape(); setupForAnsiEscape();
printfQueryMeta(); printfQueryMeta();
resetAfterAnsiEscape(); resetAfterAnsiEscape();
prompt(); prompt();
TAOS * taos = NULL; TAOS * taos = NULL;
taos = taos_connect(g_queryInfo.host, taos = taos_connect(g_queryInfo.host,
g_queryInfo.user, g_queryInfo.user,
g_queryInfo.password, g_queryInfo.password,
g_queryInfo.dbName,
g_queryInfo.port);
if (taos == NULL) {
errorPrint( "Failed to connect to TDengine, reason:%s\n",
taos_errstr(NULL));
exit(-1);
}
if (0 != g_queryInfo.superQueryInfo.sqlCount) {
getAllChildNameOfSuperTable(taos,
g_queryInfo.dbName, g_queryInfo.dbName,
g_queryInfo.superQueryInfo.sTblName, g_queryInfo.port);
&g_queryInfo.superQueryInfo.childTblName, if (taos == NULL) {
&g_queryInfo.superQueryInfo.childTblCount); errorPrint( "Failed to connect to TDengine, reason:%s\n",
} taos_errstr(NULL));
taos_close(taos); // TODO: workaround to use separate taos connection;
pthread_t *pids = NULL;
threadInfo *infos = NULL;
pthread_t *pidsOfStable = NULL;
threadInfo *infosOfStable = NULL;
//==== create threads for query for specified table
if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) {
debugPrint("%s() LN%d, sepcified query sqlCount %d.\n",
__func__, __LINE__,
g_queryInfo.specifiedQueryInfo.sqlCount);
} else {
if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) {
errorPrint("%s() LN%d, sepcified query sqlCount %d.\n",
__func__, __LINE__,
g_queryInfo.specifiedQueryInfo.sqlCount);
exit(-1); exit(-1);
} }
pids = calloc( if (0 != g_queryInfo.superQueryInfo.sqlCount) {
1, getAllChildNameOfSuperTable(taos,
g_queryInfo.specifiedQueryInfo.sqlCount * g_queryInfo.dbName,
g_queryInfo.specifiedQueryInfo.concurrent * g_queryInfo.superQueryInfo.sTblName,
sizeof(pthread_t)); &g_queryInfo.superQueryInfo.childTblName,
infos = calloc( &g_queryInfo.superQueryInfo.childTblCount);
1,
g_queryInfo.specifiedQueryInfo.sqlCount *
g_queryInfo.specifiedQueryInfo.concurrent *
sizeof(threadInfo));
if ((NULL == pids) || (NULL == infos)) {
errorPrint("%s() LN%d, malloc failed for create threads\n", __func__, __LINE__);
exit(-1);
} }
for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { taos_close(taos); // TODO: workaround to use separate taos connection;
for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) {
uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j; pthread_t *pids = NULL;
threadInfo *pThreadInfo = infos + seq; threadInfo *infos = NULL;
pThreadInfo->threadID = seq;
pThreadInfo->querySeq = i; pthread_t *pidsOfStable = NULL;
pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection; threadInfo *infosOfStable = NULL;
pthread_create(pids + seq, NULL, specifiedSubscribe, pThreadInfo);
//==== create threads for query for specified table
if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) {
debugPrint("%s() LN%d, sepcified query sqlCount %d.\n",
__func__, __LINE__,
g_queryInfo.specifiedQueryInfo.sqlCount);
} else {
if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) {
errorPrint("%s() LN%d, sepcified query sqlCount %d.\n",
__func__, __LINE__,
g_queryInfo.specifiedQueryInfo.sqlCount);
exit(-1);
} }
}
}
//==== create threads for super table query pids = calloc(
if (g_queryInfo.superQueryInfo.sqlCount <= 0) {
debugPrint("%s() LN%d, super table query sqlCount %d.\n",
__func__, __LINE__,
g_queryInfo.superQueryInfo.sqlCount);
} else {
if ((g_queryInfo.superQueryInfo.sqlCount > 0)
&& (g_queryInfo.superQueryInfo.threadCnt > 0)) {
pidsOfStable = calloc(
1, 1,
g_queryInfo.superQueryInfo.sqlCount * g_queryInfo.specifiedQueryInfo.sqlCount *
g_queryInfo.superQueryInfo.threadCnt * g_queryInfo.specifiedQueryInfo.concurrent *
sizeof(pthread_t)); sizeof(pthread_t));
infosOfStable = calloc( infos = calloc(
1, 1,
g_queryInfo.superQueryInfo.sqlCount * g_queryInfo.specifiedQueryInfo.sqlCount *
g_queryInfo.superQueryInfo.threadCnt * g_queryInfo.specifiedQueryInfo.concurrent *
sizeof(threadInfo)); sizeof(threadInfo));
if ((NULL == pidsOfStable) || (NULL == infosOfStable)) { if ((NULL == pids) || (NULL == infos)) {
errorPrint("%s() LN%d, malloc failed for create threads\n", errorPrint("%s() LN%d, malloc failed for create threads\n", __func__, __LINE__);
__func__, __LINE__);
// taos_close(taos);
exit(-1); exit(-1);
} }
int64_t ntables = g_queryInfo.superQueryInfo.childTblCount; for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) {
int threads = g_queryInfo.superQueryInfo.threadCnt; for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) {
uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j;
int64_t a = ntables / threads; threadInfo *pThreadInfo = infos + seq;
if (a < 1) { pThreadInfo->threadID = seq;
threads = ntables; pThreadInfo->querySeq = i;
a = 1; pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection;
pthread_create(pids + seq, NULL, specifiedSubscribe, pThreadInfo);
}
} }
}
int64_t b = 0; //==== create threads for super table query
if (threads != 0) { if (g_queryInfo.superQueryInfo.sqlCount <= 0) {
b = ntables % threads; debugPrint("%s() LN%d, super table query sqlCount %d.\n",
} __func__, __LINE__,
g_queryInfo.superQueryInfo.sqlCount);
} else {
if ((g_queryInfo.superQueryInfo.sqlCount > 0)
&& (g_queryInfo.superQueryInfo.threadCnt > 0)) {
pidsOfStable = calloc(
1,
g_queryInfo.superQueryInfo.sqlCount *
g_queryInfo.superQueryInfo.threadCnt *
sizeof(pthread_t));
infosOfStable = calloc(
1,
g_queryInfo.superQueryInfo.sqlCount *
g_queryInfo.superQueryInfo.threadCnt *
sizeof(threadInfo));
if ((NULL == pidsOfStable) || (NULL == infosOfStable)) {
errorPrint("%s() LN%d, malloc failed for create threads\n",
__func__, __LINE__);
// taos_close(taos);
exit(-1);
}
for (uint64_t i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { int64_t ntables = g_queryInfo.superQueryInfo.childTblCount;
uint64_t tableFrom = 0; int threads = g_queryInfo.superQueryInfo.threadCnt;
for (int j = 0; j < threads; j++) {
uint64_t seq = i * threads + j;
threadInfo *pThreadInfo = infosOfStable + seq;
pThreadInfo->threadID = seq;
pThreadInfo->querySeq = i;
pThreadInfo->start_table_from = tableFrom; int64_t a = ntables / threads;
pThreadInfo->ntables = j<b?a+1:a; if (a < 1) {
pThreadInfo->end_table_to = j<b?tableFrom+a:tableFrom+a-1; threads = ntables;
tableFrom = pThreadInfo->end_table_to + 1; a = 1;
pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection;
pthread_create(pidsOfStable + seq,
NULL, superSubscribe, pThreadInfo);
} }
}
g_queryInfo.superQueryInfo.threadCnt = threads; int64_t b = 0;
if (threads != 0) {
b = ntables % threads;
}
for (uint64_t i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) {
uint64_t tableFrom = 0;
for (int j = 0; j < threads; j++) {
uint64_t seq = i * threads + j;
threadInfo *pThreadInfo = infosOfStable + seq;
pThreadInfo->threadID = seq;
pThreadInfo->querySeq = i;
pThreadInfo->start_table_from = tableFrom;
pThreadInfo->ntables = j<b?a+1:a;
pThreadInfo->end_table_to = j<b?tableFrom+a:tableFrom+a-1;
tableFrom = pThreadInfo->end_table_to + 1;
pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection;
pthread_create(pidsOfStable + seq,
NULL, superSubscribe, pThreadInfo);
}
}
for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) { g_queryInfo.superQueryInfo.threadCnt = threads;
for (int j = 0; j < threads; j++) {
uint64_t seq = i * threads + j; for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) {
pthread_join(pidsOfStable[seq], NULL); for (int j = 0; j < threads; j++) {
uint64_t seq = i * threads + j;
pthread_join(pidsOfStable[seq], NULL);
}
} }
} }
} }
}
for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) { for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) {
for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) { for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) {
uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j; uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j;
pthread_join(pids[seq], NULL); pthread_join(pids[seq], NULL);
}
} }
}
tmfree((char*)pids); tmfree((char*)pids);
tmfree((char*)infos); tmfree((char*)infos);
tmfree((char*)pidsOfStable); tmfree((char*)pidsOfStable);
tmfree((char*)infosOfStable); tmfree((char*)infosOfStable);
// taos_close(taos); // taos_close(taos);
return 0; return 0;
} }
static void initOfInsertMeta() { static void initOfInsertMeta() {
memset(&g_Dbs, 0, sizeof(SDbs)); memset(&g_Dbs, 0, sizeof(SDbs));
// set default values // set default values
tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE); tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
g_Dbs.port = 6030; g_Dbs.port = 6030;
tstrncpy(g_Dbs.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE); tstrncpy(g_Dbs.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE);
tstrncpy(g_Dbs.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE); tstrncpy(g_Dbs.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE);
g_Dbs.threadCount = 2; g_Dbs.threadCount = 2;
g_Dbs.use_metric = g_args.use_metric; g_Dbs.use_metric = g_args.use_metric;
} }
static void initOfQueryMeta() { static void initOfQueryMeta() {
memset(&g_queryInfo, 0, sizeof(SQueryMetaInfo)); memset(&g_queryInfo, 0, sizeof(SQueryMetaInfo));
// set default values // set default values
tstrncpy(g_queryInfo.host, "127.0.0.1", MAX_HOSTNAME_SIZE); tstrncpy(g_queryInfo.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
g_queryInfo.port = 6030; g_queryInfo.port = 6030;
tstrncpy(g_queryInfo.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE); tstrncpy(g_queryInfo.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE);
tstrncpy(g_queryInfo.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE); tstrncpy(g_queryInfo.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE);
} }
static void setParaFromArg() { static void setParaFromArg() {
...@@ -8218,37 +8226,37 @@ static void setParaFromArg() { ...@@ -8218,37 +8226,37 @@ static void setParaFromArg() {
/* Function to do regular expression check */ /* Function to do regular expression check */
static int regexMatch(const char *s, const char *reg, int cflags) { static int regexMatch(const char *s, const char *reg, int cflags) {
regex_t regex; regex_t regex;
char msgbuf[100] = {0}; char msgbuf[100] = {0};
/* Compile regular expression */ /* Compile regular expression */
if (regcomp(&regex, reg, cflags) != 0) { if (regcomp(&regex, reg, cflags) != 0) {
printf("Fail to compile regex\n"); printf("Fail to compile regex\n");
exit(-1); exit(-1);
} }
/* Execute regular expression */ /* Execute regular expression */
int reti = regexec(&regex, s, 0, NULL, 0); int reti = regexec(&regex, s, 0, NULL, 0);
if (!reti) { if (!reti) {
regfree(&regex); regfree(&regex);
return 1; return 1;
} else if (reti == REG_NOMATCH) { } else if (reti == REG_NOMATCH) {
regfree(&regex); regfree(&regex);
return 0;
} else {
regerror(reti, &regex, msgbuf, sizeof(msgbuf));
printf("Regex match failed: %s\n", msgbuf);
regfree(&regex);
exit(-1);
}
return 0; return 0;
} else {
regerror(reti, &regex, msgbuf, sizeof(msgbuf));
printf("Regex match failed: %s\n", msgbuf);
regfree(&regex);
exit(-1);
}
return 0;
} }
static int isCommentLine(char *line) { static int isCommentLine(char *line) {
if (line == NULL) return 1; if (line == NULL) return 1;
return regexMatch(line, "^\\s*#.*", REG_EXTENDED); return regexMatch(line, "^\\s*#.*", REG_EXTENDED);
} }
static void querySqlFile(TAOS* taos, char* sqlFile) static void querySqlFile(TAOS* taos, char* sqlFile)
...@@ -8306,131 +8314,131 @@ static void querySqlFile(TAOS* taos, char* sqlFile) ...@@ -8306,131 +8314,131 @@ static void querySqlFile(TAOS* taos, char* sqlFile)
static void testMetaFile() { static void testMetaFile() {
if (INSERT_TEST == g_args.test_mode) { if (INSERT_TEST == g_args.test_mode) {
if (g_Dbs.cfgDir[0]) if (g_Dbs.cfgDir[0])
taos_options(TSDB_OPTION_CONFIGDIR, g_Dbs.cfgDir); taos_options(TSDB_OPTION_CONFIGDIR, g_Dbs.cfgDir);
insertTestProcess(); insertTestProcess();
} else if (QUERY_TEST == g_args.test_mode) { } else if (QUERY_TEST == g_args.test_mode) {
if (g_queryInfo.cfgDir[0]) if (g_queryInfo.cfgDir[0])
taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir); taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir);
queryTestProcess(); queryTestProcess();
} else if (SUBSCRIBE_TEST == g_args.test_mode) { } else if (SUBSCRIBE_TEST == g_args.test_mode) {
if (g_queryInfo.cfgDir[0]) if (g_queryInfo.cfgDir[0])
taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir); taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir);
subscribeTestProcess(); subscribeTestProcess();
} else { } else {
; ;
} }
} }
static void queryResult() { static void queryResult() {
// query data // query data
pthread_t read_id; pthread_t read_id;
threadInfo *pThreadInfo = calloc(1, sizeof(threadInfo)); threadInfo *pThreadInfo = calloc(1, sizeof(threadInfo));
assert(pThreadInfo); assert(pThreadInfo);
pThreadInfo->start_time = 1500000000000; // 2017-07-14 10:40:00.000 pThreadInfo->start_time = 1500000000000; // 2017-07-14 10:40:00.000
pThreadInfo->start_table_from = 0; pThreadInfo->start_table_from = 0;
//pThreadInfo->do_aggreFunc = g_Dbs.do_aggreFunc; //pThreadInfo->do_aggreFunc = g_Dbs.do_aggreFunc;
if (g_args.use_metric) { if (g_args.use_metric) {
pThreadInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount; pThreadInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount;
pThreadInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1; pThreadInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1;
pThreadInfo->superTblInfo = &g_Dbs.db[0].superTbls[0]; pThreadInfo->superTblInfo = &g_Dbs.db[0].superTbls[0];
tstrncpy(pThreadInfo->tb_prefix, tstrncpy(pThreadInfo->tb_prefix,
g_Dbs.db[0].superTbls[0].childTblPrefix, TSDB_TABLE_NAME_LEN - 20); g_Dbs.db[0].superTbls[0].childTblPrefix, TSDB_TABLE_NAME_LEN - 20);
} else { } else {
pThreadInfo->ntables = g_args.num_of_tables; pThreadInfo->ntables = g_args.num_of_tables;
pThreadInfo->end_table_to = g_args.num_of_tables -1; pThreadInfo->end_table_to = g_args.num_of_tables -1;
tstrncpy(pThreadInfo->tb_prefix, g_args.tb_prefix, TSDB_TABLE_NAME_LEN); tstrncpy(pThreadInfo->tb_prefix, g_args.tb_prefix, TSDB_TABLE_NAME_LEN);
} }
pThreadInfo->taos = taos_connect( pThreadInfo->taos = taos_connect(
g_Dbs.host, g_Dbs.host,
g_Dbs.user, g_Dbs.user,
g_Dbs.password, g_Dbs.password,
g_Dbs.db[0].dbName, g_Dbs.db[0].dbName,
g_Dbs.port); g_Dbs.port);
if (pThreadInfo->taos == NULL) { if (pThreadInfo->taos == NULL) {
errorPrint( "Failed to connect to TDengine, reason:%s\n", errorPrint( "Failed to connect to TDengine, reason:%s\n",
taos_errstr(NULL)); taos_errstr(NULL));
free(pThreadInfo);
exit(-1);
}
tstrncpy(pThreadInfo->filePath, g_Dbs.resultFile, MAX_FILE_NAME_LEN);
if (!g_Dbs.use_metric) {
pthread_create(&read_id, NULL, readTable, pThreadInfo);
} else {
pthread_create(&read_id, NULL, readMetric, pThreadInfo);
}
pthread_join(read_id, NULL);
taos_close(pThreadInfo->taos);
free(pThreadInfo); free(pThreadInfo);
exit(-1);
}
tstrncpy(pThreadInfo->filePath, g_Dbs.resultFile, MAX_FILE_NAME_LEN);
if (!g_Dbs.use_metric) {
pthread_create(&read_id, NULL, readTable, pThreadInfo);
} else {
pthread_create(&read_id, NULL, readMetric, pThreadInfo);
}
pthread_join(read_id, NULL);
taos_close(pThreadInfo->taos);
free(pThreadInfo);
} }
static void testCmdLine() { static void testCmdLine() {
if (strlen(configDir)) { if (strlen(configDir)) {
wordexp_t full_path; wordexp_t full_path;
if (wordexp(configDir, &full_path, 0) != 0) { if (wordexp(configDir, &full_path, 0) != 0) {
errorPrint( "Invalid path %s\n", configDir); errorPrint( "Invalid path %s\n", configDir);
return; return;
}
taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]);
wordfree(&full_path);
} }
taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]);
wordfree(&full_path);
}
g_args.test_mode = INSERT_TEST; g_args.test_mode = INSERT_TEST;
insertTestProcess(); insertTestProcess();
if (false == g_Dbs.insert_only) if (false == g_Dbs.insert_only)
queryResult(); queryResult();
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
parse_args(argc, argv, &g_args); parse_args(argc, argv, &g_args);
debugPrint("meta file: %s\n", g_args.metaFile);
if (g_args.metaFile) { debugPrint("meta file: %s\n", g_args.metaFile);
initOfInsertMeta();
initOfQueryMeta();
if (false == getInfoFromJsonFile(g_args.metaFile)) { if (g_args.metaFile) {
printf("Failed to read %s\n", g_args.metaFile); initOfInsertMeta();
return 1; initOfQueryMeta();
}
testMetaFile(); if (false == getInfoFromJsonFile(g_args.metaFile)) {
} else { printf("Failed to read %s\n", g_args.metaFile);
memset(&g_Dbs, 0, sizeof(SDbs)); return 1;
setParaFromArg(); }
if (NULL != g_args.sqlFile) {
TAOS* qtaos = taos_connect(
g_Dbs.host,
g_Dbs.user,
g_Dbs.password,
g_Dbs.db[0].dbName,
g_Dbs.port);
querySqlFile(qtaos, g_args.sqlFile);
taos_close(qtaos);
testMetaFile();
} else { } else {
testCmdLine(); memset(&g_Dbs, 0, sizeof(SDbs));
} setParaFromArg();
if (NULL != g_args.sqlFile) {
TAOS* qtaos = taos_connect(
g_Dbs.host,
g_Dbs.user,
g_Dbs.password,
g_Dbs.db[0].dbName,
g_Dbs.port);
querySqlFile(qtaos, g_args.sqlFile);
taos_close(qtaos);
if (g_dupstr) } else {
free(g_dupstr); testCmdLine();
} }
return 0; if (g_dupstr)
free(g_dupstr);
}
return 0;
} }
...@@ -5,6 +5,8 @@ IF (TD_LINUX) ...@@ -5,6 +5,8 @@ IF (TD_LINUX)
AUX_SOURCE_DIRECTORY(. SRC) AUX_SOURCE_DIRECTORY(. SRC)
ADD_EXECUTABLE(demo apitest.c) ADD_EXECUTABLE(demo apitest.c)
TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread ) TARGET_LINK_LIBRARIES(demo taos_static trpc tutil pthread )
ADD_EXECUTABLE(sml schemaless.c)
TARGET_LINK_LIBRARIES(sml taos_static trpc tutil pthread )
ADD_EXECUTABLE(subscribe subscribe.c) ADD_EXECUTABLE(subscribe subscribe.c)
TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread ) TARGET_LINK_LIBRARIES(subscribe taos_static trpc tutil pthread )
ADD_EXECUTABLE(epoll epoll.c) ADD_EXECUTABLE(epoll epoll.c)
......
...@@ -964,21 +964,31 @@ int32_t verify_schema_less(TAOS* taos) { ...@@ -964,21 +964,31 @@ int32_t verify_schema_less(TAOS* taos) {
usleep(100000); usleep(100000);
char* lines[] = { char* lines[] = {
"st,t1=3i,t2=4,t3=\"t3\" c1=3i,c3=L\"passit\",c2=false,c4=4 1626006833639000000", "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000ns",
"st,t1=4i,t3=\"t4\",t2=5,t4=5 c1=3i,c3=L\"passitagin\",c2=true,c4=5,c5=5 1626006833640000000", "st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000ns",
"ste,t2=5,t3=L\"ste\" c1=true,c2=4,c3=\"iam\" 1626056811823316532", "ste,t2=5f64,t3=L\"ste\" c1=true,c2=4i64,c3=\"iam\" 1626056811823316532ns",
"st,t1=4i,t2=5,t3=\"t4\" c1=3i,c3=L\"passitagain\",c2=true,c4=5 1626006833642000000", "st,t1=4i64,t2=5f64,t3=\"t4\" c1=3i64,c3=L\"passitagain\",c2=true,c4=5f64 1626006833642000000ns",
"ste,t2=5,t3=L\"ste2\" c3=\"iamszhou\",c4=false 1626056811843316532", "ste,t2=5f64,t3=L\"ste2\" c3=\"iamszhou\",c4=false 1626056811843316532ns",
"ste,t2=5,t3=L\"ste2\" c3=\"iamszhou\",c4=false,c5=32b,c6=64s,c7=32w,c8=88.88f 1626056812843316532", "ste,t2=5f64,t3=L\"ste2\" c3=\"iamszhou\",c4=false,c5=32i8,c6=64i16,c7=32i32,c8=88.88f32 1626056812843316532ns",
"st,t1=4i,t3=\"t4\",t2=5,t4=5 c1=3i,c3=L\"passitagin\",c2=true,c4=5,c5=5,c6=7u 1626006933640000000", "st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000ns",
"stf,t1=4i,t3=\"t4\",t2=5,t4=5 c1=3i,c3=L\"passitagin\",c2=true,c4=5,c5=5,c6=7u 1626006933640000000", "stf,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000ns",
"stf,t1=4i,t3=\"t4\",t2=5,t4=5 c1=3i,c3=L\"passitagin_stf\",c2=false,c5=5,c6=7u 1626006933641a" "stf,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641000000ns"
}; };
// int code = taos_insert_lines(taos, lines , sizeof(lines)/sizeof(char*)); int code = 0;
int code = taos_insert_lines(taos, &lines[0], 1); code = taos_insert_lines(taos, lines , sizeof(lines)/sizeof(char*));
code = taos_insert_lines(taos, &lines[1], 1); char* lines2[] = {
"stg,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000ns",
"stg,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000ns"
};
code = taos_insert_lines(taos, &lines2[0], 1);
code = taos_insert_lines(taos, &lines2[1], 1);
char* lines3[] = {
"sth,t1=4i64,t2=5f64,t4=5f64,ID=\"childtable\" c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641ms",
"sth,t1=4i64,t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933654ms"
};
code = taos_insert_lines(taos, lines3, 2);
return code; return code;
} }
...@@ -1000,10 +1010,8 @@ int main(int argc, char *argv[]) { ...@@ -1000,10 +1010,8 @@ int main(int argc, char *argv[]) {
printf("client info: %s\n", info); printf("client info: %s\n", info);
printf("************ verify shemaless *************\n"); printf("************ verify shemaless *************\n");
int code = verify_schema_less(taos); verify_schema_less(taos);
if (code == 0) {
return code;
}
printf("************ verify query *************\n"); printf("************ verify query *************\n");
verify_query(taos); verify_query(taos);
......
#include "taos.h"
#include "taoserror.h"
#include "os.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
int numSuperTables = 8;
int numChildTables = 1024;
int numRowsPerChildTable = 128;
void shuffle(char**lines, size_t n)
{
if (n > 1)
{
size_t i;
for (i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
char* t = lines[j];
lines[j] = lines[i];
lines[i] = t;
}
}
}
static int64_t getTimeInUs() {
struct timeval systemTime;
gettimeofday(&systemTime, NULL);
return (int64_t)systemTime.tv_sec * 1000000L + (int64_t)systemTime.tv_usec;
}
int main(int argc, char* argv[]) {
TAOS_RES *result;
const char* host = "127.0.0.1";
const char* user = "root";
const char* passwd = "taosdata";
taos_options(TSDB_OPTION_TIMEZONE, "GMT-8");
TAOS* taos = taos_connect(host, user, passwd, "", 0);
if (taos == NULL) {
printf("\033[31mfailed to connect to db, reason:%s\033[0m\n", taos_errstr(taos));
exit(1);
}
char* info = taos_get_server_info(taos);
printf("server info: %s\n", info);
info = taos_get_client_info(taos);
printf("client info: %s\n", info);
result = taos_query(taos, "drop database if exists db;");
taos_free_result(result);
usleep(100000);
result = taos_query(taos, "create database db precision 'ms';");
taos_free_result(result);
usleep(100000);
(void)taos_select_db(taos, "db");
time_t ct = time(0);
int64_t ts = ct * 1000;
char* lineFormat = "sta%d,t0=true,t1=127i8,t2=32767i16,t3=%di32,t4=9223372036854775807i64,t9=11.12345f32,t10=22.123456789f64,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c0=true,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=255u8,c6=32770u16,c7=2147483699u32,c8=9223372036854775899u64,c9=11.12345f32,c10=22.123456789f64,c11=\"binaryValue\",c12=L\"ncharValue\" %lldms";
char** lines = calloc(numSuperTables * numChildTables * numRowsPerChildTable, sizeof(char*));
int l = 0;
for (int i = 0; i < numSuperTables; ++i) {
for (int j = 0; j < numChildTables; ++j) {
for (int k = 0; k < numRowsPerChildTable; ++k) {
char* line = calloc(512, 1);
snprintf(line, 512, lineFormat, i, j, ts + 10 * l);
lines[l] = line;
++l;
}
}
}
shuffle(lines, numSuperTables * numChildTables * numRowsPerChildTable);
printf("%s\n", "begin taos_insert_lines");
int64_t begin = getTimeInUs();
int32_t code = taos_insert_lines(taos, lines, numSuperTables * numChildTables * numRowsPerChildTable);
int64_t end = getTimeInUs();
printf("code: %d, %s. time used: %"PRId64"\n", code, tstrerror(code), end-begin);
char* lines_000_0[] = {
"sta1,id=sta1_1,t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=255u8,t6=32770u16,t7=2147483699u32,t8=9223372036854775899u64,t9=11.12345f32,t10=22.123456789f64,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c0=true,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=255u8,c6=32770u16,c7=2147483699u32,c8=9223372036854775899u64,c9=11.12345f32,c10=22.123456789f64,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006833639000us"
};
code = taos_insert_lines(taos, lines_000_0 , sizeof(lines_000_0)/sizeof(char*));
if (0 == code) {
printf("taos_insert_lines() lines_000_0 should return error\n");
return -1;
}
char* lines_000_1[] = {
"sta2,id=\"sta2_1\",t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=255u8,t6=32770u16,t7=2147483699u32,t8=9223372036854775899u64,t9=11.12345f32,t10=22.123456789f64,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c0=true,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=255u8,c6=32770u16,c7=2147483699u32,c8=9223372036854775899u64,c9=11.12345f32,c10=22.123456789f64,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006833639001"
};
code = taos_insert_lines(taos, lines_000_1 , sizeof(lines_000_1)/sizeof(char*));
if (0 == code) {
printf("taos_insert_lines() lines_000_1 should return error\n");
return -1;
}
char* lines_000_2[] = {
"sta3,id=\"sta3_1\",t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t9=11.12345f32,t10=22.123456789f64,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c0=true,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=255u8,c6=32770u16,c7=2147483699u32,c8=9223372036854775899u64,c9=11.12345f32,c10=22.123456789f64,c11=\"binaryValue\",c12=L\"ncharValue\" 0"
};
code = taos_insert_lines(taos, lines_000_2 , sizeof(lines_000_2)/sizeof(char*));
if (0 != code) {
printf("taos_insert_lines() lines_000_2 return code:%d (%s)\n", code, (char*)tstrerror(code));
return -1;
}
char* lines_001_0[] = {
"sta4,t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t9=11.12345f32,t10=22.123456789f64,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c0=true,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c9=11.12345f32,c10=22.123456789f64,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006833639000us",
};
code = taos_insert_lines(taos, lines_001_0 , sizeof(lines_001_0)/sizeof(char*));
if (0 != code) {
printf("taos_insert_lines() lines_001_0 return code:%d (%s)\n", code, (char*)tstrerror(code));
return -1;
}
char* lines_001_1[] = {
"sta5,id=\"sta5_1\",t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t9=11.12345f32,t10=22.123456789f64,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c0=true,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c9=11.12345f32,c10=22.123456789f64,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006833639001"
};
code = taos_insert_lines(taos, lines_001_1 , sizeof(lines_001_1)/sizeof(char*));
if (0 != code) {
printf("taos_insert_lines() lines_001_1 return code:%d (%s)\n", code, (char*)tstrerror(code));
return -1;
}
char* lines_001_2[] = {
"sta6,id=\"sta6_1\",t0=true,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t9=11.12345f32,t10=22.123456789f64,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c0=true,c1=127i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c9=11.12345f32,c10=22.123456789f64,c11=\"binaryValue\",c12=L\"ncharValue\" 0"
};
code = taos_insert_lines(taos, lines_001_2 , sizeof(lines_001_2)/sizeof(char*));
if (0 != code) {
printf("taos_insert_lines() lines_001_2 return code:%d (%s)\n", code, (char*)tstrerror(code));
return -1;
}
char* lines_002[] = {
"stb,id=\"stb_1\",t20=t,t21=T,t22=true,t23=True,t24=TRUE,t25=f,t26=F,t27=false,t28=False,t29=FALSE,t10=33.12345,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c20=t,c21=T,c22=true,c23=True,c24=TRUE,c25=f,c26=F,c27=false,c28=False,c29=FALSE,c10=33.12345,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006833639000000ns",
"stc,id=\"stc_1\",t20=t,t21=T,t22=true,t23=True,t24=TRUE,t25=f,t26=F,t27=false,t28=False,t29=FALSE,t10=33.12345,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c20=t,c21=T,c22=true,c23=True,c24=TRUE,c25=f,c26=F,c27=false,c28=False,c29=FALSE,c10=33.12345,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006833639019us",
"stc,id=\"stc_1\",t20=t,t21=T,t22=true,t23=True,t24=TRUE,t25=f,t26=F,t27=false,t28=False,t29=FALSE,t10=33.12345,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c20=t,c21=T,c22=true,c23=True,c24=TRUE,c25=f,c26=F,c27=false,c28=False,c29=FALSE,c10=33.12345,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006833640ms",
"stc,id=\"stc_1\",t20=t,t21=T,t22=true,t23=True,t24=TRUE,t25=f,t26=F,t27=false,t28=False,t29=FALSE,t10=33.12345,t11=\"binaryTagValue\",t12=L\"ncharTagValue\" c20=t,c21=T,c22=true,c23=True,c24=TRUE,c25=f,c26=F,c27=false,c28=False,c29=FALSE,c10=33.12345,c11=\"binaryValue\",c12=L\"ncharValue\" 1626006834s"
};
code = taos_insert_lines(taos, lines_002 , sizeof(lines_002)/sizeof(char*));
if (0 != code) {
printf("taos_insert_lines() lines_002 return code:%d (%s)\n", code, (char*)tstrerror(code));
return -1;
}
return 0;
}
...@@ -27,6 +27,7 @@ python3 ./test.py -f insert/bug3654.py ...@@ -27,6 +27,7 @@ python3 ./test.py -f insert/bug3654.py
python3 ./test.py -f insert/insertDynamicColBeforeVal.py python3 ./test.py -f insert/insertDynamicColBeforeVal.py
python3 ./test.py -f insert/in_function.py python3 ./test.py -f insert/in_function.py
python3 ./test.py -f insert/modify_column.py python3 ./test.py -f insert/modify_column.py
python3 ./test.py -f insert/line_insert.py
#table #table
python3 ./test.py -f table/alter_wal0.py python3 ./test.py -f table/alter_wal0.py
......
###################################################################
# Copyright (c) 2021 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
from util.log import *
from util.cases import *
from util.sql import *
class TDTestCase:
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
self._conn = conn
def run(self):
print("running {}".format(__file__))
tdSql.execute("drop database if exists test")
tdSql.execute("create database if not exists test precision 'us'")
tdSql.execute('use test')
tdSql.execute('create stable ste(ts timestamp, f int) tags(t1 bigint)')
lines = [ "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000ns",
"st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000ns",
"ste,t2=5f64,t3=L\"ste\" c1=true,c2=4i64,c3=\"iam\" 1626056811823316532ns",
"stf,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000ns",
"st,t1=4i64,t2=5f64,t3=\"t4\" c1=3i64,c3=L\"passitagain\",c2=true,c4=5f64 1626006833642000000ns",
"ste,t2=5f64,t3=L\"ste2\" c3=\"iamszhou\",c4=false 1626056811843316532ns",
"ste,t2=5f64,t3=L\"ste2\" c3=\"iamszhou\",c4=false,c5=32i8,c6=64i16,c7=32i32,c8=88.88f32 1626056812843316532ns",
"st,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000ns",
"stf,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641000000ns"
]
code = self._conn.insertLines(lines)
print("insertLines result {}".format(code))
lines2 = [ "stg,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000ns",
"stg,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833640000000ns"
]
code = self._conn.insertLines([ lines2[0] ])
print("insertLines result {}".format(code))
self._conn.insertLines([ lines2[1] ])
print("insertLines result {}".format(code))
tdSql.query("select * from st")
tdSql.checkRows(4)
tdSql.query("select * from ste")
tdSql.checkRows(3)
tdSql.query("select * from stf")
tdSql.checkRows(2)
tdSql.query("select * from stg")
tdSql.checkRows(2)
tdSql.query("show tables")
tdSql.checkRows(8)
tdSql.query("describe stf")
tdSql.checkData(2, 2, 14)
self._conn.insertLines([
"sth,t1=4i64,t2=5f64,t4=5f64,ID=\"childtable\" c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933641ms",
"sth,t1=4i64,t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin_stf\",c2=false,c5=5f64,c6=7u64 1626006933654ms"
])
tdSql.query('select tbname, * from sth')
tdSql.checkRows(2)
tdSql.query('select tbname, * from childtable')
tdSql.checkRows(1)
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())
...@@ -105,6 +105,7 @@ run general/parser/import_commit2.sim ...@@ -105,6 +105,7 @@ run general/parser/import_commit2.sim
run general/parser/import_commit3.sim run general/parser/import_commit3.sim
run general/parser/insert_tb.sim run general/parser/insert_tb.sim
run general/parser/first_last.sim run general/parser/first_last.sim
run general/parser/line_insert.sim
#unsupport run general/parser/import_file.sim #unsupport run general/parser/import_file.sim
run general/parser/lastrow.sim run general/parser/lastrow.sim
run general/parser/nchar.sim run general/parser/nchar.sim
......
...@@ -16,11 +16,10 @@ sql create database $db precision 'us' ...@@ -16,11 +16,10 @@ sql create database $db precision 'us'
sql use $db sql use $db
sql create stable $mte (ts timestamp, f int) TAGS(t1 bigint) sql create stable $mte (ts timestamp, f int) TAGS(t1 bigint)
line_insert st,t1=3i,t2=4,t3="t3" c1=3i,c3=L"passit",c2=false,c4=4 1626006833639000000 line_insert st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"passit",c2=false,c4=4f64 1626006833639000000ns
line_insert st,t1=4i,t3="t41",t2=5 c1=3i,c3=L"passiT",c2=true,c4=5 1626006833640000000 line_insert st,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin",c2=true,c4=5f64,c5=5f64 1626006833640000000ns
line_insert stf,t1=4i,t2=5,t3="t4" c1=3i,c3=L"passitagain",c2=true,c4=5 1626006833642000000 line_insert ste,t2=5f64,t3=L"ste" c1=true,c2=4i64,c3="iam" 1626056811823316532ns
line_insert ste,t2=5,t3=L"ste" c1=true,c2=4,c3="iam" 1626056811823316532 line_insert stf,t1=4i64,t3="t4",t2=5f64,t4=5f64 c1=3i64,c3=L"passitagin",c2=true,c4=5f64,c5=5f64,c6=7u64 1626006933640000000ns
sql select * from st sql select * from st
if $rows != 2 then if $rows != 2 then
return -1 return -1
...@@ -30,7 +29,7 @@ if $data00 != @21-07-11 20:33:53.639000@ then ...@@ -30,7 +29,7 @@ if $data00 != @21-07-11 20:33:53.639000@ then
return -1 return -1
endi endi
if $data03 != @passit@ then if $data02 != @passit@ then
return -1 return -1
endi endi
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册