/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "os.h" #include "sim.h" #include "taos.h" #include "taoserror.h" #include "tglobal.h" #include "tutil.h" #include "cJSON.h" void simLogSql(char *sql) { static FILE *fp = NULL; char filename[256]; sprintf(filename, "%s/sim.sql", scriptDir); if (fp == NULL) { fp = fopen(filename, "w"); if (fp == NULL) { fprintf(stderr, "ERROR: failed to open file: %s\n", filename); return; } } fprintf(fp, "%s;\n", sql); fflush(fp); } char *simGetVariable(SScript *script, char *varName, int varLen) { if (strncmp(varName, "error", varLen) == 0) return script->error; if (strncmp(varName, "rows", varLen) == 0) return script->rows; if (strncmp(varName, "system_exit", varLen) == 0) return script->system_exit_code; if (strncmp(varName, "system_content", varLen) == 0) return script->system_ret_content; // variable like data2_192.168.0.1 if (strncmp(varName, "data", 4) == 0) { if (varLen < 6) { return "null"; } if (varName[5] == '_') { int col = varName[4] - '0'; if (col < 0 || col >= MAX_QUERY_COL_NUM) { return "null"; } char *keyName; int keyLen; paGetToken(varName + 6, &keyName, &keyLen); for (int i = 0; i < MAX_QUERY_ROW_NUM; ++i) { if (strncmp(keyName, script->data[i][0], keyLen) == 0) { simTrace("script:%s, keyName:%s, keyValue:%s", script->fileName, script->data[i][0], script->data[i][col]); return script->data[i][col]; } } return "null"; } else { int row = varName[4] - '0'; int col = varName[5] - '0'; if (row < 0 || row >= MAX_QUERY_ROW_NUM) { return "null"; } if (col < 0 || col >= MAX_QUERY_COL_NUM) { return "null"; } simTrace("script:%s, data[%d][%d]=%s", script->fileName, row, col, script->data[row][col]); return script->data[row][col]; } } for (int i = 0; i < script->varLen; ++i) { SVariable *var = &script->variables[i]; if (var->varNameLen != varLen) { continue; } if (strncmp(varName, var->varName, varLen) == 0) { // if (strlen(var->varValue) != 0) // simTrace("script:%s, var:%s, value:%s", script->fileName, // var->varName, var->varValue); return var->varValue; } } if (script->varLen >= MAX_VAR_LEN) { simError("script:%s, too many varialbes:%d", script->fileName, script->varLen); exit(0); } SVariable *var = &script->variables[script->varLen]; script->varLen++; strncpy(var->varName, varName, varLen); var->varNameLen = varLen; var->varValue[0] = 0; return var->varValue; } int simExecuteExpression(SScript *script, char *exp) { char *op1, *op2, *var1, *var2, *var3, *rest; int op1Len, op2Len, var1Len, var2Len, var3Len, val0, val1; char t0[512], t1[512], t2[512], t3[512]; int result; rest = paGetToken(exp, &var1, &var1Len); rest = paGetToken(rest, &op1, &op1Len); rest = paGetToken(rest, &var2, &var2Len); rest = paGetToken(rest, &op2, &op2Len); if (var1[0] == '$') strcpy(t0, simGetVariable(script, var1 + 1, var1Len - 1)); else { memcpy(t0, var1, var1Len); t0[var1Len] = 0; } if (var2[0] == '$') strcpy(t1, simGetVariable(script, var2 + 1, var2Len - 1)); else { memcpy(t1, var2, var2Len); t1[var2Len] = 0; } if (op2Len != 0) { rest = paGetToken(rest, &var3, &var3Len); if (var3[0] == '$') strcpy(t2, simGetVariable(script, var3 + 1, var3Len - 1)); else { memcpy(t2, var3, var3Len); t2[var3Len] = 0; } if (op2[0] == '+') { sprintf(t3, "%lld", atoll(t1) + atoll(t2)); } else if (op2[0] == '-') { sprintf(t3, "%lld", atoll(t1) - atoll(t2)); } else if (op2[0] == '*') { sprintf(t3, "%lld", atoll(t1) * atoll(t2)); } else if (op2[0] == '/') { sprintf(t3, "%lld", atoll(t1) / atoll(t2)); } else if (op2[0] == '.') { sprintf(t3, "%s%s", t1, t2); } } else { strcpy(t3, t1); } result = 0; if (op1Len == 1) { if (op1[0] == '=') { strcpy(simGetVariable(script, var1 + 1, var1Len - 1), t3); } else if (op1[0] == '<') { val0 = atoi(t0); val1 = atoi(t3); if (val0 >= val1) result = -1; } else if (op1[0] == '>') { val0 = atoi(t0); val1 = atoi(t3); if (val0 <= val1) result = -1; } } else { if (op1[0] == '=' && op1[1] == '=') { if (strcmp(t0, t3) != 0) result = -1; } else if (op1[0] == '!' && op1[1] == '=') { if (strcmp(t0, t3) == 0) result = -1; } else if (op1[0] == '<' && op1[1] == '=') { val0 = atoi(t0); val1 = atoi(t3); if (val0 > val1) result = -1; } else if (op1[0] == '>' && op1[1] == '=') { val0 = atoi(t0); val1 = atoi(t3); if (val0 < val1) result = -1; } } return result; } bool simExecuteExpCmd(SScript *script, char *option) { simExecuteExpression(script, option); script->linePos++; return true; } bool simExecuteTestCmd(SScript *script, char *option) { int result; result = simExecuteExpression(script, option); if (result >= 0) script->linePos++; else script->linePos = script->lines[script->linePos].jump; return true; } bool simExecuteGotoCmd(SScript *script, char *option) { script->linePos = script->lines[script->linePos].jump; return true; } bool simExecuteRunCmd(SScript *script, char *option) { char *fileName = option; if (fileName == NULL || strlen(fileName) == 0) { sprintf(script->error, "lineNum:%d. script file is null", script->lines[script->linePos].lineNum); return false; } SScript *newScript = simParseScript(option); if (newScript == NULL) { sprintf(script->error, "lineNum:%d. parse file:%s error", script->lines[script->linePos].lineNum, fileName); return false; } simPrint("script:%s, start to execute", newScript->fileName); newScript->type = SIM_SCRIPT_TYPE_MAIN; simScriptPos++; simScriptList[simScriptPos] = newScript; script->linePos++; return true; } bool simExecuteRunBackCmd(SScript *script, char *option) { char *fileName = option; if (fileName == NULL || strlen(fileName) == 0) { sprintf(script->error, "lineNum:%d. script file is null", script->lines[script->linePos].lineNum); return false; } SScript *newScript = simParseScript(option); if (newScript == NULL) { sprintf(script->error, "lineNum:%d. parse file:%s error", script->lines[script->linePos].lineNum, fileName); return false; } simPrint("script:%s, start to execute in background", newScript->fileName); newScript->type = SIM_SCRIPT_TYPE_BACKGROUND; script->bgScripts[script->bgScriptLen++] = newScript; pthread_t pid; if (pthread_create(&pid, NULL, simExecuteScript, (void *)newScript) != 0) { sprintf(script->error, "lineNum:%d. create background thread failed", script->lines[script->linePos].lineNum); return false; } script->linePos++; return true; } bool simExecuteSystemCmd(SScript *script, char *option) { char buf[4096] = {0}; sprintf(buf, "cd %s; ", scriptDir); simVisuallizeOption(script, option, buf + strlen(buf)); int code = system(buf); int repeatTimes = 0; while (code < 0) { simError("script:%s, failed to execute %s , code %d, errno:%d %s, repeatTimes:%d", script->fileName, buf, code, errno, strerror(errno), repeatTimes); taosMsleep(1000); signal(SIGCHLD, SIG_DFL); if (repeatTimes++ >= 10) { exit(0); } } sprintf(script->system_exit_code, "%d", code); script->linePos++; return true; } void simStoreSystemContentResult(SScript *script, char *filename) { memset(script->system_ret_content, 0, MAX_SYSTEM_RESULT_LEN); FILE *fd; if ((fd = fopen(filename, "r")) != NULL) { fread(script->system_ret_content, 1, MAX_SYSTEM_RESULT_LEN - 1, fd); fclose(fd); char rmCmd[MAX_FILE_NAME_LEN] = {0}; sprintf(rmCmd, "rm -f %s", filename); system(rmCmd); } } bool simExecuteSystemContentCmd(SScript *script, char *option) { char buf[4096] = {0}; char filename[400] = {0}; sprintf(filename, "%s/%s.tmp", scriptDir, script->fileName); sprintf(buf, "cd %s; ", scriptDir); simVisuallizeOption(script, option, buf + strlen(buf)); sprintf(buf, "%s > %s 2>/dev/null", buf, filename); sprintf(script->system_exit_code, "%d", system(buf)); simStoreSystemContentResult(script, filename); script->linePos++; return true; } bool simExecutePrintCmd(SScript *script, char *rest) { char buf[65536]; simVisuallizeOption(script, rest, buf); rest = buf; simPrint("script:%s, %s", script->fileName, rest); script->linePos++; return true; } bool simExecuteSleepCmd(SScript *script, char *option) { int delta; char buf[1024]; simVisuallizeOption(script, option, buf); option = buf; delta = atoi(option); if (delta <= 0) delta = 5; simPrint("script:%s, sleep %dms begin", script->fileName, delta); taosMsleep(delta); simPrint("script:%s, sleep %dms finished", script->fileName, delta); script->linePos++; return true; } bool simExecuteReturnCmd(SScript *script, char *option) { char buf[1024]; simVisuallizeOption(script, option, buf); option = buf; int ret = 1; if (option && option[0] != 0) ret = atoi(option); if (ret < 0) { sprintf(script->error, "lineNum:%d. error return %s", script->lines[script->linePos].lineNum, option); return false; } else { simPrint("script:%s, return cmd execute with:%d", script->fileName, ret); script->linePos = script->numOfLines; } script->linePos++; return true; } void simVisuallizeOption(SScript *script, char *src, char *dst) { char *var, *token, *value; int dstLen, srcLen, tokenLen; dst[0] = 0, dstLen = 0; while (1) { var = strchr(src, '$'); if (var == NULL) break; if (var && ((var - src - 1) > 0) && *(var - 1) == '\\') { srcLen = var - src - 1; memcpy(dst + dstLen, src, srcLen); dstLen += srcLen; src = var; break; } srcLen = var - src; memcpy(dst + dstLen, src, srcLen); dstLen += srcLen; src = paGetToken(var + 1, &token, &tokenLen); value = simGetVariable(script, token, tokenLen); strcpy(dst + dstLen, value); dstLen += strlen(value); } strcpy(dst + dstLen, src); } void simCloseRestFulConnect(SScript *script) { memset(script->auth, 0, sizeof(script->auth)); } void simCloseNativeConnect(SScript *script) { if (script->taos == NULL) return; simTrace("script:%s, taos:%p closed", script->fileName, script->taos); taos_close(script->taos); script->taos = NULL; } void simCloseTaosdConnect(SScript *script) { if (simAsyncQuery) { return simCloseRestFulConnect(script); } else { return simCloseNativeConnect(script); } } // {"status":"succ","code":0,"desc":"/KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04"} // {"status":"succ","head":["affected_rows"],"data":[[1]],"rows":1} // {"status":"succ","head":["ts","i"],"data":[["2017-12-25 21:28:41.022",1],["2017-12-25 21:28:42.022",2],["2017-12-25 21:28:43.022",3],["2017-12-25 21:28:44.022",4],["2017-12-25 21:28:45.022",5],["2017-12-25 21:28:46.022",6],["2017-12-25 21:28:47.022",7],["2017-12-25 21:28:48.022",8],["2017-12-25 21:28:49.022",9],["2017-12-25 21:28:50.022",10]],"rows":10} int simParseHttpCommandResult(SScript *script, char *command) { cJSON* root = cJSON_Parse(command); if (root == NULL) { simError("script:%s, failed to parse json, response:%s", script->fileName, command); return -1; } cJSON *status = cJSON_GetObjectItem(root, "status"); if (status == NULL) { simError("script:%s, failed to parse json, status is null, response:%s", script->fileName, command); cJSON_Delete(root); return -1; } if (status->valuestring == NULL || strlen(status->valuestring) == 0) { simError("script:%s, failed to parse json, status value is null, response:%s", script->fileName, command); cJSON_Delete(root); return -1; } if (strcmp(status->valuestring, "succ") != 0) { cJSON *code = cJSON_GetObjectItem(root, "code"); if (code == NULL) { simError("script:%s, failed to parse json, code is null, response:%s", script->fileName, command); cJSON_Delete(root); return -1; } int retcode = (int)code->valueint; if (retcode != 1017) { simError("script:%s, json:status:%s not equal to succ, response:%s", script->fileName, status->valuestring, command); cJSON_Delete(root); return retcode; } else { simTrace("script:%s, json:status:%s not equal to succ, but code is %d, response:%s", script->fileName, status->valuestring, retcode, command); cJSON_Delete(root); return 0; } } cJSON *desc = cJSON_GetObjectItem(root, "desc"); if (desc != NULL) { if (desc->valuestring == NULL || strlen(desc->valuestring) == 0) { simError("script:%s, failed to parse json, desc value is null, response:%s", script->fileName, command); cJSON_Delete(root); return -1; } strcpy(script->auth, desc->valuestring); cJSON_Delete(root); return 0; } cJSON *data = cJSON_GetObjectItem(root, "data"); if (data == NULL) { simError("script:%s, failed to parse json, data is null, response:%s", script->fileName, command); cJSON_Delete(root); return -1; } int rowsize = cJSON_GetArraySize(data); if (rowsize < 0) { simError("script:%s, failed to parse json:data, data size %d, response:%s", script->fileName, rowsize, command); cJSON_Delete(root); return -1; } int rowIndex = 0; sprintf(script->rows, "%d", rowsize); for (int r = 0; r < rowsize; ++r) { cJSON *row = cJSON_GetArrayItem(data, r); if (row == NULL) continue; if (rowIndex++ >= 10) break; int colsize = cJSON_GetArraySize(row); if (colsize < 0) { break; } colsize = MIN(10, colsize); for (int c = 0; c < colsize; ++c) { cJSON *col = cJSON_GetArrayItem(row, c); if (col->valuestring != NULL) { strcpy(script->data[r][c], col->valuestring); } else { if (col->numberstring[0] == 0) { strcpy(script->data[r][c], "null"); } else { strcpy(script->data[r][c], col->numberstring); } } } } return 0; } int simExecuteRestFulCommand(SScript *script, char *command) { char buf[5000] = {0}; sprintf(buf, "%s 2>/dev/null", command); FILE *fp = popen(buf, "r"); if (fp == NULL) { simError("failed to execute %s", buf); return TSDB_CODE_OTHERS; } int mallocSize = 2000; int alreadyReadSize = 0; char* content = malloc(mallocSize); while (!feof(fp)) { int availSize = mallocSize - alreadyReadSize; int len = fread(content + alreadyReadSize, 1, availSize, fp); if (len >= availSize) { alreadyReadSize += len; mallocSize *= 2; content = realloc(content, mallocSize); } } pclose(fp); return simParseHttpCommandResult(script, content); } bool simCreateRestFulConnect(SScript *script, char *user, char *pass) { char command[4096]; sprintf(command, "curl 127.0.0.1:6020/rest/login/%s/%s", user, pass); bool success = false; for (int attempt = 0; attempt < 10; ++attempt) { success = simExecuteRestFulCommand(script, command) == 0; if (!success) { simTrace("script:%s, user:%s connect taosd failed:%s, attempt:%d", script->fileName, user, taos_errstr(NULL), attempt); taosMsleep(1000); } else { simTrace("script:%s, user:%s connect taosd successed, attempt:%d", script->fileName, user, attempt); break; } } if (!success) { sprintf(script->error, "lineNum:%d. connect taosd failed:%s", script->lines[script->linePos].lineNum, taos_errstr(NULL)); return false; } simTrace("script:%s, connect taosd successed, auth:%p", script->fileName, script->auth); return true; } bool simCreateNativeConnect(SScript *script, char *user, char *pass) { simCloseTaosdConnect(script); void *taos = NULL; taosMsleep(2000); for (int attempt = 0; attempt < 10; ++attempt) { taos = taos_connect(NULL, user, pass, NULL, tsMnodeShellPort); if (taos == NULL) { simTrace("script:%s, user:%s connect taosd failed:%s, attempt:%d", script->fileName, user, taos_errstr(NULL), attempt); taosMsleep(1000); } else { simTrace("script:%s, user:%s connect taosd successed, attempt:%d", script->fileName, user, attempt); break; } } if (taos == NULL) { sprintf(script->error, "lineNum:%d. connect taosd failed:%s", script->lines[script->linePos].lineNum, taos_errstr(NULL)); return false; } script->taos = taos; simTrace("script:%s, connect taosd successed, taos:%p", script->fileName, taos); return true; } bool simCreateTaosdConnect(SScript *script, char *rest) { char *user = tsDefaultUser; char *token; int tokenLen; rest = paGetToken(rest, &token, &tokenLen); rest = paGetToken(rest, &token, &tokenLen); if (tokenLen != 0) { user = token; } if (simAsyncQuery) { return simCreateRestFulConnect(script, user, tsDefaultPass); } else { return simCreateNativeConnect(script, user, tsDefaultPass); } } bool simExecuteNativeSqlCommand(SScript *script, char *rest, bool isSlow) { char timeStr[30] = {0}; time_t tt; struct tm *tp; SCmdLine *line = &script->lines[script->linePos]; int ret = -1; for (int attempt = 0; attempt < 3; ++attempt) { simLogSql(rest); ret = taos_query(script->taos, rest); if (ret == TSDB_CODE_TABLE_ALREADY_EXIST || ret == TSDB_CODE_DB_ALREADY_EXIST) { simTrace("script:%s, taos:%p, %s success, ret:%d:%s", script->fileName, script->taos, rest, ret, tstrerror(ret)); ret = 0; break; } else if (ret != 0) { simTrace("script:%s, taos:%p, %s failed, ret:%d:%s, error:%s", script->fileName, script->taos, rest, ret, tstrerror(ret), taos_errstr(script->taos)); if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } taosMsleep(1000); } else { break; } } if (ret) { sprintf(script->error, "lineNum:%d. sql:%s failed, ret:%d:%s", line->lineNum, rest, ret, tstrerror(ret)); return false; } int numOfRows = 0; int num_fields = taos_field_count(script->taos); if (num_fields != 0) { TAOS_RES *result = taos_use_result(script->taos); if (result == NULL) { simTrace("script:%s, taos:%p, %s failed, result is null", script->fileName, script->taos, rest); if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } sprintf(script->error, "lineNum:%d. result set null, sql:%s", line->lineNum, rest); return false; } TAOS_ROW row; while ((row = taos_fetch_row(result))) { if (numOfRows < MAX_QUERY_ROW_NUM) { TAOS_FIELD *fields = taos_fetch_fields(result); for (int i = 0; i < num_fields; i++) { char *value = NULL; if (i < MAX_QUERY_COL_NUM) { value = script->data[numOfRows][i]; } if (value == NULL) { continue; } if (row[i] == 0) { strcpy(value, "null"); continue; } switch (fields[i].type) { case TSDB_DATA_TYPE_BOOL: sprintf(value, "%s", ((((int)(*((char *)row[i]))) == 1) ? "1" : "0")); break; case TSDB_DATA_TYPE_TINYINT: sprintf(value, "%d", (int)(*((char *)row[i]))); break; case TSDB_DATA_TYPE_SMALLINT: sprintf(value, "%d", (int)(*((short *)row[i]))); break; case TSDB_DATA_TYPE_INT: sprintf(value, "%d", *((int *)row[i])); break; case TSDB_DATA_TYPE_BIGINT: #ifdef _TD_ARM_32_ sprintf(value, "%lld", *((int64_t *)row[i])); #else sprintf(value, "%ld", *((int64_t *)row[i])); #endif break; case TSDB_DATA_TYPE_FLOAT:{ #ifdef _TD_ARM_32_ float fv = 0; *(int32_t*)(&fv) = *(int32_t*)row[i]; sprintf(value, "%.5f", fv); #else sprintf(value, "%.5f", *((float *)row[i])); #endif } break; case TSDB_DATA_TYPE_DOUBLE: { #ifdef _TD_ARM_32_ double dv = 0; *(int64_t*)(&dv) = *(int64_t*)row[i]; sprintf(value, "%.9lf", dv); #else sprintf(value, "%.9lf", *((double *)row[i])); #endif } break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: memcpy(value, row[i], fields[i].bytes); value[fields[i].bytes] = 0; // snprintf(value, fields[i].bytes, "%s", (char *)row[i]); break; case TSDB_DATA_TYPE_TIMESTAMP: tt = *(int64_t *)row[i] / 1000; tp = localtime(&tt); strftime(timeStr, 64, "%y-%m-%d %H:%M:%S", tp); sprintf(value, "%s.%03d", timeStr, (int)(*((int64_t *)row[i]) % 1000)); break; default: break; } // end of switch } // end of for } // end of if numOfRows++; if (isSlow && numOfRows % 100 == 0) { taosMsleep(200); } if (numOfRows > 2000000000) { simError("script:%s, too many rows return from query", script->fileName); break; } } taos_free_result(result); } else { numOfRows = taos_affected_rows(script->taos); } sprintf(script->rows, "%d", numOfRows); script->linePos++; return true; } bool simExecuteRestFulSqlCommand(SScript *script, char *rest) { SCmdLine *line = &script->lines[script->linePos]; char command[4096]; sprintf(command, "curl -H 'Authorization: Taosd %s' -d \"%s\" 127.0.0.1:6020/rest/sql", script->auth, rest); int ret = -1; for (int attempt = 0; attempt < 10; ++attempt) { ret = simExecuteRestFulCommand(script, command); if (ret == TSDB_CODE_TABLE_ALREADY_EXIST || ret == TSDB_CODE_DB_ALREADY_EXIST) { simTrace("script:%s, taos:%p, %s success, ret:%d:%s", script->fileName, script->taos, rest, ret, tstrerror(ret)); ret = 0; break; } else if (ret != 0) { simTrace("script:%s, taos:%p, %s failed, ret:%d", script->fileName, script->taos, rest, ret); if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } taosMsleep(1000); } else { break; } } if (ret) { sprintf(script->error, "lineNum:%d. sql:%s failed, ret:%d", line->lineNum, rest, ret); return false; } script->linePos++; return true; } bool simExecuteSqlImpCmd(SScript *script, char *rest, bool isSlow) { char buf[3000]; SCmdLine *line = &script->lines[script->linePos]; simVisuallizeOption(script, rest, buf); rest = buf; simTrace("script:%s, exec:%s", script->fileName, rest); strcpy(script->rows, "-1"); for (int row = 0; row < MAX_QUERY_ROW_NUM; ++row) { for (int col = 0; col < MAX_QUERY_COL_NUM; ++col) { strcpy(script->data[row][col], "null"); } } if (strncmp(rest, "connect", 7) == 0) { if (!simCreateTaosdConnect(script, rest)) { return false; } script->linePos++; return true; } if ((!simAsyncQuery && script->taos == NULL) || (simAsyncQuery && script->auth[0] == 0)) { if (!simCreateTaosdConnect(script, "connect root")) { if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } return false; } } if (strncmp(rest, "close", 5) == 0) { simCloseTaosdConnect(script); script->linePos++; return true; } if (simAsyncQuery) { return simExecuteRestFulSqlCommand(script, rest); } else { return simExecuteNativeSqlCommand(script, rest, isSlow); } } bool simExecuteSqlCmd(SScript *script, char *rest) { bool isSlow = false; return simExecuteSqlImpCmd(script, rest, isSlow); } bool simExecuteSqlSlowCmd(SScript *script, char *rest) { bool isSlow = true; return simExecuteSqlImpCmd(script, rest, isSlow); } bool simExecuteSqlErrorCmd(SScript *script, char *rest) { char buf[3000]; SCmdLine *line = &script->lines[script->linePos]; simVisuallizeOption(script, rest, buf); rest = buf; simTrace("script:%s, exec:%s", script->fileName, rest); strcpy(script->rows, "-1"); for (int row = 0; row < MAX_QUERY_ROW_NUM; ++row) { for (int col = 0; col < MAX_QUERY_COL_NUM; ++col) { strcpy(script->data[row][col], "null"); } } if (strncmp(rest, "connect", 7) == 0) { if (!simCreateTaosdConnect(script, rest)) { return false; } script->linePos++; return true; } if ((!simAsyncQuery && script->taos == NULL) || (simAsyncQuery && script->auth[0] == 0)) { if (!simCreateTaosdConnect(script, "connect root")) { if (line->errorJump == SQL_JUMP_TRUE) { script->linePos = line->jump; return true; } return false; } } if (strncmp(rest, "close", 5) == 0) { simCloseTaosdConnect(script); script->linePos++; return true; } int ret; if (simAsyncQuery) { char command[4096]; sprintf(command, "curl -H 'Authorization: Taosd %s' -d '%s' 127.0.0.1:6020/rest/sql", script->auth, rest); ret = simExecuteRestFulCommand(script, command); } else { ret = taos_query(script->taos, rest); } if (ret != TSDB_CODE_SUCCESS) { simTrace("script:%s, taos:%p, %s execute, expect failed, so success, ret:%d:%s", script->fileName, script->taos, rest, ret, tstrerror(ret)); script->linePos++; return true; } sprintf(script->error, "lineNum:%d. sql:%s expect failed, but success, ret:%d:%s", line->lineNum, rest, ret, tstrerror(ret)); return false; }