提交 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) {
...@@ -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;
if (*c != '+' && *c != '-' && *c != '.' && !isdigit(*c)) {
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;
}
char* value; static bool isTinyInt(char *pVal, uint16_t len) {
}SLPItem; if (len <= 2) {
return false;
}
if (!strcmp(&pVal[len - 2], "i8")) {
//printf("Type is int8(%s)\n", pVal);
return true;
}
return false;
}
typedef struct { static bool isTinyUint(char *pVal, uint16_t len) {
SStrToken measToken; if (len <= 2) {
SStrToken tsToken; return false;
}
if (pVal[0] == '-') {
return false;
}
if (!strcmp(&pVal[len - 2], "u8")) {
//printf("Type is uint8(%s)\n", pVal);
return true;
}
return false;
}
char sTableName[TSDB_TABLE_NAME_LEN]; static bool isSmallInt(char *pVal, uint16_t len) {
SArray* tags; if (len <= 3) {
SArray* fields; return false;
int64_t ts; }
if (!strcmp(&pVal[len - 3], "i16")) {
//printf("Type is int16(%s)\n", pVal);
return true;
}
return false;
}
} SLPPoint; static bool isSmallUint(char *pVal, uint16_t len) {
if (len <= 3) {
return false;
}
if (pVal[0] == '-') {
return false;
}
if (strcmp(&pVal[len - 3], "u16") == 0) {
//printf("Type is uint16(%s)\n", pVal);
return true;
}
return false;
}
typedef enum { static bool isInt(char *pVal, uint16_t len) {
LP_MEASUREMENT, if (len <= 3) {
LP_TAG_KEY, return false;
LP_TAG_VALUE,
LP_FIELD_KEY,
LP_FIELD_VALUE
} LPPart;
int32_t scanToCommaOrSpace(SStrToken s, int32_t start, int32_t* index, LPPart part) {
for (int32_t i = start; i < s.n; ++i) {
if (s.z[i] == ',' || s.z[i] == ' ') {
*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;
}
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;
}
static bool isBinary(char *pVal, uint16_t len) {
//binary: "abc"
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 { } else {
return (int)(t1->keyToken.n) - (int)(t2->keyToken.n); return false;
}
} }
//printf("Type is timestamp(%s)\n", pVal);
return true;
}
return false;
} }
int32_t setPointTimeStamp(SLPPoint* point, SStrToken tsToken) { //len does not include '\0' from value.
point->tsToken = tsToken; static bool convertSmlValueType(TAOS_SML_KV *pVal, char *value,
return 0; 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;
if (*last == 's') {
point->ts *= (int64_t)1e9;
} else if (*last == 'a') {
point->ts *= (int64_t)1e6;
} else if (*last == 'u') {
point->ts *= (int64_t)1e3;
} else if (*last == 'b') {
point->ts *= 1;
} }
switch (type) {
case SML_TIME_STAMP_NOW: {
*ts = taosGetTimestampNs();
break;
} }
return 0; case SML_TIME_STAMP_SECONDS: {
*ts = (int64_t)(*ts * 1e9);
break;
}
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 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++;
} }
SStrToken tagKey = {.z = line.z + start, .n = pos-start}; if (len > 0) {
setItemKey(&item, tagKey, LP_TAG_KEY); value = calloc(len + 1, 1);
memcpy(value, start, len);
}
start = pos + 1; ret = convertSmlTimeStamp(*pTS, value, len);
err = scanToCommaOrSpace(line, start, &pos, LP_TAG_VALUE); if (ret) {
if (err != 0) { free(value);
tscError("c"); free(*pTS);
goto error; return ret;
} }
free(value);
SStrToken tagValue = {.z = line.z + start, .n = pos-start}; (*pTS)->key = calloc(sizeof(key), 1);
setItemValue(&item, tagValue, LP_TAG_VALUE); memcpy((*pTS)->key, key, sizeof(key));
return ret;
}
parseItemValue(&item, LP_ITEM_TAG); static int32_t parseSmlKey(TAOS_SML_KV *pKV, const char **index) {
taosArrayPush(point->tags, &item); const char *cur = *index;
char key[TSDB_COL_NAME_LEN];
uint16_t len = 0;
start = pos; //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';
taosArraySort(point->tags, compareLPItemKey); 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;
}
point->fields = taosArrayInit(64, sizeof(SLPItem));
start++; static bool parseSmlValue(TAOS_SML_KV *pKV, const char **index,
do { bool *is_last_kv) {
SLPItem item; const char *start, *cur;
char *value = NULL;
uint16_t len = 0;
start = cur = *index;
err = scanToEqual(line, start, &pos); while (1) {
if (err != 0) { // unescaped ',' or ' ' or '\0' identifies a value
goto error; 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 fieldKey = {.z = line.z + start, .n = pos- start};
setItemKey(&item, fieldKey, LP_FIELD_KEY);
start = pos + 1; value = calloc(len + 1, 1);
err = scanToCommaOrSpace(line, start, &pos, LP_FIELD_VALUE); memcpy(value, start, len);
if (err != 0) { value[len] = '\0';
goto error; if (!convertSmlValueType(pKV, value, len)) {
//free previous alocated key field
free(pKV->key);
free(value);
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} }
SStrToken fieldValue = {.z = line.z + start, .n = pos - start}; free(value);
setItemValue(&item, fieldValue, LP_TAG_VALUE);
parseItemValue(&item, LP_ITEM_FIELD); *index = (*cur == '\0') ? cur : cur + 1;
taosArrayPush(point->fields, &item); return TSDB_CODE_SUCCESS;
}
start = pos + 1; static int32_t parseSmlMeasurement(TAOS_SML_DATA_POINT *pSml, const char **index,
} while (line.z[pos] == ','); 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;
}
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);
taosArraySort(point->fields, compareLPItemKey); return TSDB_CODE_SUCCESS;
}
SStrToken tsToken = {.z = line.z+start, .n = line.n-start}; static int32_t parseSmlKvPairs(TAOS_SML_KV **pKVs, int *num_kvs,
setPointTimeStamp(point, tsToken); const char **index, bool isField, TAOS_SML_DATA_POINT* smlData) {
parsePointTime(point); 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;
}
while (*cur != '\0') {
ret = parseSmlKey(pkv, &cur);
if (ret) {
tscError("Unable to parse key field");
goto error;
}
ret = parseSmlValue(pkv, &cur, &is_last_kv);
if (ret) {
tscError("Unable to parse value field");
goto error;
}
if (!isField &&
(strcasecmp(pkv->key, "ID") == 0) && pkv->type == TSDB_DATA_TYPE_BINARY) {
smlData->childTableName = malloc( pkv->length + 1);
memcpy(smlData->childTableName, pkv->value, pkv->length);
smlData->childTableName[pkv->length] = '\0';
free(pkv->key);
free(pkv->value);
} else {
*num_kvs += 1;
}
if (is_last_kv) {
//tscDebug("last key-value field detected");
goto done; goto done;
}
error: //reallocate addtional memory for more kvs
// free array TAOS_SML_KV *more_kvs = NULL;
return err;
done:
return 0;
}
if (isField) {
if ((*num_kvs + 2) > capacity) {
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;
}
}
int32_t tscParseLines(char* lines[], int numLines, SArray* points, SArray* failedLines) { if (!more_kvs) {
for (int32_t i = 0; i < numLines; ++i) { goto error;
SStrToken tkLine = {.z = lines[i], .n = (uint32_t)strlen(lines[i])};
SLPPoint point;
tscParseLine(tkLine, &point);
taosArrayPush(points, &point);
} }
return 0; *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;
error:
return ret;
done:
*index = cur;
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);
} }
void destroyLPPoint(void* p) { int32_t tscParseLine(const char* sql, TAOS_SML_DATA_POINT* smlData) {
SLPPoint* lpPoint = p; const char* index = sql;
for (int i=0; i<taosArrayGetSize(lpPoint->fields); ++i) { int32_t ret = TSDB_CODE_SUCCESS;
SLPItem* item = taosArrayGet(lpPoint->fields, i); uint8_t has_tags = 0;
free(item->value); TAOS_SML_KV *timestamp = NULL;
ret = parseSmlMeasurement(smlData, &index, &has_tags);
if (ret) {
tscError("Unable to parse measurement");
return ret;
} }
taosArrayDestroy(lpPoint->fields); tscDebug("Parse measurement finished, has_tags:%d", has_tags);
for (int i=0; i<taosArrayGetSize(lpPoint->tags); ++i) { //Parse Tags
SLPItem* item = taosArrayGet(lpPoint->tags, i); if (has_tags) {
free(item->value); ret = parseSmlKvPairs(&smlData->tags, &smlData->tagNum, &index, false, smlData);
if (ret) {
tscError("Unable to parse tag");
return ret;
} }
taosArrayDestroy(lpPoint->tags); }
tscDebug("Parse tags finished, num of tags:%d", smlData->tagNum);
//Parse fields
ret = parseSmlKvPairs(&smlData->fields, &smlData->fieldNum, &index, true, smlData);
if (ret) {
tscError("Unable to parse field");
return ret;
}
tscDebug("Parse fields finished, num of fields:%d", smlData->fieldNum);
//Parse timestamp
ret = parseSmlTimeStamp(&timestamp, &index);
if (ret) {
tscError("Unable to parse timestamp");
return ret;
}
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);
if (code != TSDB_CODE_SUCCESS) {
tscError("data point line parse failed. line %d : %s", i, lines[i]);
destroySmlDataPoint(&point);
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
} else {
tscDebug("data point line parse success. line %d", i);
}
size_t numPoints = taosArrayGetSize(lpPoints); taosArrayPush(points, &point);
TAOS_SML_DATA_POINT* points = calloc(numPoints, sizeof(TAOS_SML_DATA_POINT)); }
for (int i = 0; i < numPoints; ++i) { return 0;
SLPPoint* lpPoint = taosArrayGet(lpPoints, i); }
TAOS_SML_DATA_POINT* point = points+i;
point->stableName = calloc(1, strlen(lpPoint->sTableName)+1);
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); int taos_insert_lines(TAOS* taos, char* lines[], int numLines) {
tagKv->key = calloc(1, kenLen+1); int32_t code = 0;
strncpy(tagKv->key, lpTag->key, kenLen);
tagKv->key[kenLen] = '\0';
tagKv->type = lpTag->type; if (numLines <= 0 || numLines > 65536) {
tagKv->length = lpTag->length; tscError("taos_insert_lines numLines should be between 1 and 65536. numLines: %d", numLines);
tagKv->value = malloc(tagKv->length); code = TSDB_CODE_TSC_APP_ERROR;
memcpy(tagKv->value, lpTag->value, tagKv->length); return code;
} }
size_t lpFieldsSize = taosArrayGetSize(lpPoint->fields); for (int i = 0; i < numLines; ++i) {
point->fields = calloc(lpFieldsSize + 1, sizeof(TAOS_SML_KV)); if (lines[i] == NULL) {
point->fieldNum = (int)(lpFieldsSize + 1); tscError("taos_insert_lines line %d is NULL", i);
code = TSDB_CODE_TSC_APP_ERROR;
TAOS_SML_KV* tsField = point->fields + 0; return code;
char tsKey[256]; }
snprintf(tsKey, 256, "_%s_ts", point->stableName); }
size_t tsKeyLen = strlen(tsKey);
tsField->key = calloc(1, tsKeyLen+1);
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,7 +485,7 @@ typedef unsigned __int32 uint32_t; ...@@ -485,7 +485,7 @@ 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;
...@@ -2697,7 +2697,7 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, ...@@ -2697,7 +2697,7 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName,
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;
...@@ -3270,7 +3270,7 @@ static void createChildTables() { ...@@ -3270,7 +3270,7 @@ 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;
...@@ -3338,7 +3338,7 @@ static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) { ...@@ -3338,7 +3338,7 @@ static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) {
/* /*
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;
...@@ -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__);
...@@ -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;
} }
...@@ -6570,7 +6573,7 @@ static void callBack(void *param, TAOS_RES *res, int code) { ...@@ -6570,7 +6573,7 @@ static void callBack(void *param, TAOS_RES *res, int code) {
pstr += sprintf(pstr, "insert into %s.%s%"PRId64" values", pstr += sprintf(pstr, "insert into %s.%s%"PRId64" values",
pThreadInfo->db_name, pThreadInfo->tb_prefix, pThreadInfo->db_name, pThreadInfo->tb_prefix,
pThreadInfo->start_table_from); pThreadInfo->start_table_from);
// if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) { // if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) {
if (pThreadInfo->counter >= g_args.num_of_RPR) { if (pThreadInfo->counter >= g_args.num_of_RPR) {
pThreadInfo->start_table_from++; pThreadInfo->start_table_from++;
pThreadInfo->counter = 0; pThreadInfo->counter = 0;
...@@ -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(?");
...@@ -7027,12 +7035,12 @@ static void *readTable(void *sarg) { ...@@ -7027,12 +7035,12 @@ static void *readTable(void *sarg) {
} }
int64_t num_of_DPT; int64_t num_of_DPT;
/* if (pThreadInfo->superTblInfo) { /* if (pThreadInfo->superTblInfo) {
num_of_DPT = pThreadInfo->superTblInfo->insertRows; // nrecords_per_table; num_of_DPT = pThreadInfo->superTblInfo->insertRows; // nrecords_per_table;
} else { } else {
*/ */
num_of_DPT = g_args.num_of_DPT; 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 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;
...@@ -7591,7 +7599,7 @@ static int queryTestProcess() { ...@@ -7591,7 +7599,7 @@ static int queryTestProcess() {
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 +
...@@ -7817,7 +7825,7 @@ static void *superSubscribe(void *sarg) { ...@@ -7817,7 +7825,7 @@ 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");
...@@ -8076,7 +8084,7 @@ static int subscribeTestProcess() { ...@@ -8076,7 +8084,7 @@ static int subscribeTestProcess() {
tmfree((char*)pidsOfStable); tmfree((char*)pidsOfStable);
tmfree((char*)infosOfStable); tmfree((char*)infosOfStable);
// taos_close(taos); // taos_close(taos);
return 0; 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.
先完成此消息的编辑!
想要评论请 注册