• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #4473

08 Jul 2025 09:38AM UTC coverage: 62.922% (+0.7%) from 62.22%
#4473

push

travis-ci

web-flow
Merge pull request #31712 from taosdata/merge/mainto3.0

merge: from main to 3.0 branch

158525 of 321496 branches covered (49.31%)

Branch coverage included in aggregate %.

56 of 60 new or added lines in 13 files covered. (93.33%)

1333 existing lines in 67 files now uncovered.

245526 of 320647 relevant lines covered (76.57%)

17689640.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.54
/tools/taos-tools/src/benchData.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the MIT license as published by the Free Software
6
 * Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12

13
#include <stdio.h>
14
#include <stdint.h>
15
#include <stdlib.h>
16
#include <stdbool.h>
17
#include <string.h>
18

19

20
#include <bench.h>
21
#include "benchLog.h"
22
#include <math.h>
23
#include <benchData.h>
24
#include "decimal.h"
25

26

27
const char charset[] =
28
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
29

30
const char* locations[] = {
31
    "California.SanFrancisco", "California.LosAngles",
32
    "California.SanDiego", "California.SanJose",
33
    "California.PaloAlto", "California.Campbell",
34
    "California.MountainView", "California.Sunnyvale",
35
    "California.SantaClara", "California.Cupertino"};
36

37
const char* locations_sml[] = {
38
    "California.SanFrancisco", "California.LosAngles",
39
    "California.SanDiego", "California.SanJose",
40
    "California.PaloAlto", "California.Campbell",
41
    "California.MountainView", "California.Sunnyvale",
42
    "California.SantaClara", "California.Cupertino"};
43

44
#ifdef WINDOWS
45
    // TODO: why define ssize_t in this way?
46
    #define ssize_t int
47
    // #if _MSC_VER >= 1910
48
    //     #include "benchLocations.h"
49
    // #else
50
    //     #include "benchLocationsWin.h"
51
    // #endif
52
    // NOTE: benchLocations.h is UTF-8 encoded, while benchLocationsWin.h is ANSI/GB18030 encoded.
53
    //       we don't want to use /utf-8 option in MSVC which will bring more considerations,
54
    //       so we use ANSI/GB18030 encoded file for the moment.
55
    #include "benchLocationsWin.h"
56
#else
57
    #include "benchLocations.h"
58
#endif
59

60
int32_t funCount(int32_t min, int32_t max, int32_t step, int32_t loop) {
×
61
    if(step == 0) {
×
62
        step = 1;
×
63
    }
64

65
    int32_t range = abs(max - min);
×
66
    int32_t maxCnt = range / step;
×
67
    int32_t val = min + (loop % maxCnt) * step ;
×
68

69
    return val;
×
70
}
71

72
int32_t funSaw(int32_t min, int32_t max, int32_t period, int32_t loop) {
1,432,814✔
73
    if(period == 0) {
1,432,814✔
74
        period = 1;
1,422,814✔
75
    }
76
    int32_t range = abs(max - min);
1,432,814✔
77
    int32_t step = range / period;
1,432,814✔
78
    int32_t val = min + (loop % period) * step ;
1,432,814✔
79
    return val;
1,432,814✔
80
}
81

82
int32_t funSquare(int32_t min, int32_t max, int32_t period, int32_t loop) {
1,452,814✔
83
    if(period == 0) {
1,452,814✔
84
        period = 1;
1,442,814✔
85
    }
86
    int32_t change = (loop/period) % 2;
1,452,814✔
87
    if (change)
1,452,814✔
88
       return min;
726,406✔
89
    else
90
       return max;
726,408✔
91
}
92

93
int32_t funTriAngle(int32_t min, int32_t max, int32_t period, int32_t loop) {
×
94
    if(period == 0) {
×
95
        period = 1;
×
96
    }
97
    int32_t range = abs(max - min);
×
98
    int32_t change = (loop/period) % 2;
×
99
    int32_t step = range/period;
×
100
    int32_t cnt = 0;    
×
101
    if(change)
×
102
       cnt = period - loop % period;
×
103
    else
104
       cnt = loop % period;
×
105

106
    return min + cnt * step;
×
107
}
108

109

110
// calc expression value like 10*sin(x) + 100
111
float funValueFloat(Field *field, int32_t angle, int32_t loop) {
2,925,632✔
112
    float radian = ATOR(angle);
2,925,632✔
113
    float funVal = 0;
2,925,632✔
114

115
    if (field->funType == FUNTYPE_SIN)
2,925,632✔
116
       funVal = sin(radian);
1,492,818✔
117
    else if (field->funType == FUNTYPE_COS)
1,432,814!
118
       funVal = cos(radian);
×
119
    else if (field->funType == FUNTYPE_COUNT)
1,432,814!
120
       funVal = (float)funCount(field->min, field->max, field->step, loop);
×
121
    else if (field->funType == FUNTYPE_SAW)
1,432,814!
122
       funVal = (float)funSaw(field->min, field->max, field->period, loop + field->offset );
1,432,814✔
123
    else if (field->funType == FUNTYPE_SQUARE)
×
124
       funVal = (float)funSquare(field->min, field->max, field->period, loop + field->offset);
×
125
    else if (field->funType == FUNTYPE_TRI)
×
126
       funVal = (float)funTriAngle(field->min, field->max, field->period, loop + field->offset);
×
127

128
    if(field->multiple != 0)
2,925,632!
129
       funVal *= field->multiple;
2,925,632✔
130
    
131
    if ( field->addend !=0 && field->random > 0 ) {
2,925,632!
132
        float rate = taosRandom() % field->random;
2,925,632✔
133
        funVal += field->addend * (rate/100);
2,925,632✔
134
    } else if(field->addend !=0 ) {
×
135
        funVal += field->addend;
×
136
    }
137

138
    funVal += field->base;
2,925,632✔
139
    return funVal;
2,925,632✔
140
}
141

142
// calc expression value like 10*sin(x) + 100
143
int32_t funValueInt32(Field *field, int32_t angle, int32_t loop) {
1,452,814✔
144
    float radian = ATOR(angle);
1,452,814✔
145
    int32_t funVal = 0;
1,452,814✔
146

147
    if (field->funType == FUNTYPE_SIN)
1,452,814!
148
       funVal = (int32_t)sin(radian);
×
149
    else if (field->funType == FUNTYPE_COS)
1,452,814!
150
       funVal = (int32_t)cos(radian);
×
151
    else if (field->funType == FUNTYPE_COUNT)
1,452,814!
152
       funVal = funCount(field->min, field->max, field->step, loop);
×
153
    else if (field->funType == FUNTYPE_SAW)
1,452,814!
154
       funVal = funSaw(field->min, field->max, field->period, loop + field->offset );
×
155
    else if (field->funType == FUNTYPE_SQUARE)
1,452,814!
156
       funVal = funSquare(field->min, field->max, field->period, loop + field->offset);
1,452,814✔
157
    else if (field->funType == FUNTYPE_TRI)
×
158
       funVal = funTriAngle(field->min, field->max, field->period, loop + field->offset);
×
159

160
    if(field->multiple != 0)
1,452,814!
161
       funVal *= field->multiple;
1,452,814✔
162
    
163
    if ( field->addend !=0 && field->random > 0 ) {
1,452,814!
164
        float rate = taosRandom() % field->random;
1,452,814✔
165
        funVal += field->addend * (rate/100);
1,452,814✔
166
    } else if(field->addend !=0 ) {
×
167
        funVal += field->addend;
×
168
    }
169

170
    funVal += field->base;
1,452,814✔
171

172
    return funVal;
1,452,814✔
173
}
174

175

176
static int usc2utf8(char *p, int unic) {
1,968✔
177
    int ret = 0;
1,968✔
178
    if (unic <= 0x0000007F) {
1,968!
179
        *p = (unic & 0x7F);
×
180
        ret = 1;
×
181
    } else if (unic <= 0x000007FF) {
1,968!
182
        *(p + 1) = (unic & 0x3F) | 0x80;
×
183
        *p = ((unic >> 6) & 0x1F) | 0xC0;
×
184
        ret = 2;
×
185
    } else if (unic <= 0x0000FFFF) {
1,968!
186
        *(p + 2) = (unic & 0x3F) | 0x80;
1,968✔
187
        *(p + 1) = ((unic >> 6) & 0x3F) | 0x80;
1,968✔
188
        *p = ((unic >> 12) & 0x0F) | 0xE0;
1,968✔
189
        ret = 3;
1,968✔
190
    } else if (unic <= 0x001FFFFF) {
×
191
        *(p + 3) = (unic & 0x3F) | 0x80;
×
192
        *(p + 2) = ((unic >> 6) & 0x3F) | 0x80;
×
193
        *(p + 1) = ((unic >> 12) & 0x3F) | 0x80;
×
194
        *p = ((unic >> 18) & 0x07) | 0xF0;
×
195
        ret = 4;
×
196
    } else if (unic <= 0x03FFFFFF) {
×
197
        *(p + 4) = (unic & 0x3F) | 0x80;
×
198
        *(p + 3) = ((unic >> 6) & 0x3F) | 0x80;
×
199
        *(p + 2) = ((unic >> 12) & 0x3F) | 0x80;
×
200
        *(p + 1) = ((unic >> 18) & 0x3F) | 0x80;
×
201
        *p = ((unic >> 24) & 0x03) | 0xF8;
×
202
        ret = 5;
×
203
    // } else if (unic >= 0x04000000) {
204
    } else {
205
        *(p + 5) = (unic & 0x3F) | 0x80;
×
206
        *(p + 4) = ((unic >> 6) & 0x3F) | 0x80;
×
207
        *(p + 3) = ((unic >> 12) & 0x3F) | 0x80;
×
208
        *(p + 2) = ((unic >> 18) & 0x3F) | 0x80;
×
209
        *(p + 1) = ((unic >> 24) & 0x3F) | 0x80;
×
210
        *p = ((unic >> 30) & 0x01) | 0xFC;
×
211
        ret = 6;
×
212
    }
213

214
    return ret;
1,968✔
215
}
216

217
void rand_string(char *str, int size, bool chinese) {
38,014,039✔
218
    if (chinese) {
38,014,039✔
219
        char *pstr = str;
428✔
220
        while (size > 0) {
2,396✔
221
            // Chinese Character need 3 bytes space
222
            if (size < 3) {
2,246✔
223
                break;
278✔
224
            }
225
            // Basic Chinese Character's Unicode is from 0x4e00 to 0x9fa5
226
            int unic = 0x4e00 + taosRandom() % (0x9fa5 - 0x4e00);
1,968✔
227
            int move = usc2utf8(pstr, unic);
1,968✔
228
            pstr += move;
1,968✔
229
            size -= move;
1,968✔
230
        }
231
    } else {
232
        str[0] = 0;
38,013,611✔
233
        if (size > 0) {
38,013,611✔
234
            // --size;
235
            int n;
236
            for (n = 0; n < size; n++) {
617,176,383✔
237
                int key = taosRandom() % (unsigned int)(sizeof(charset) - 1);
581,908,902✔
238
                str[n] = charset[key];
582,034,817✔
239
            }
240
            str[n] = 0;
35,267,481✔
241
        }
242
    }
243
}
38,139,954✔
244

245
// generate prepare sql
246
char* genPrepareSql(SSuperTable *stbInfo, char* tagData, uint64_t tableSeq, char *db) {
20,116✔
247
    int   len = 0;
20,116✔
248
    char *prepare = benchCalloc(1, TSDB_MAX_ALLOWED_SQL_LEN, true);
20,116✔
249
    int n;
250
    char *tagQ = NULL;
20,121✔
251
    char *colQ = genQMark(stbInfo->cols->size);
20,121✔
252
    char *colNames = NULL;
20,112✔
253
    bool  tagQFree = false;
20,112✔
254

255
    if(tagData == NULL) {
20,112✔
256
        // if no tagData , replace with QMark
257
        tagQ = genQMark(stbInfo->tags->size);
105✔
258
        tagQFree = true;
105✔
259
    } else {
260
        tagQ = tagData + stbInfo->lenOfTags * tableSeq;
20,007✔
261
    }
262

263
    if (stbInfo->autoTblCreating) {
20,112✔
264
        char ttl[SMALL_BUFF_LEN] = "";
20,012✔
265
        if (stbInfo->ttl != 0) {
20,012!
266
            snprintf(ttl, SMALL_BUFF_LEN, "TTL %d", stbInfo->ttl);
×
267
        }
268
        n = snprintf(prepare + len,
20,012✔
269
                       TSDB_MAX_ALLOWED_SQL_LEN - len,
20,012✔
270
                       "INSERT INTO ? USING `%s`.`%s` TAGS (%s) %s VALUES(?,%s)",
271
                       db, stbInfo->stbName, tagQ, ttl, colQ);
272
    } else {
273
        if (workingMode(g_arguments->connMode, g_arguments->dsn) == CONN_MODE_NATIVE) {
100✔
274
            // native
275
            n = snprintf(prepare + len, TSDB_MAX_ALLOWED_SQL_LEN - len,
97✔
276
                "INSERT INTO ? VALUES(?,%s)", colQ);
277
        } else {
278
            // websocket
279
            bool ntb = stbInfo->tags == NULL || stbInfo->tags->size == 0; // normal table
6!
280
            colNames = genColNames(stbInfo->cols, !ntb);
6✔
281
            n = snprintf(prepare + len, TSDB_MAX_ALLOWED_SQL_LEN - len,
6!
282
                "INSERT INTO `%s`.`%s`(%s) VALUES(%s,%s)", db, stbInfo->stbName, colNames,
283
                ntb ? "?" : "?,?", colQ);
284
        }
285
    }
286
    len += n;
20,115✔
287

288
    // free
289
    if (tagQFree) {
20,115✔
290
        tmfree(tagQ);
103✔
291
    }
292
    tmfree(colQ);
20,115✔
293
    tmfree(colNames);
20,117✔
294

295
    // check valid
296
    if (g_arguments->prepared_rand < g_arguments->reqPerReq) {
20,119!
297
        infoPrint(
×
298
                  "in stmt mode, batch size(%u) can not larger than prepared "
299
                  "sample data size(%" PRId64
300
                  "), restart with larger prepared_rand or batch size will be "
301
                  "auto set to %" PRId64 "\n",
302
                  g_arguments->reqPerReq, g_arguments->prepared_rand,
303
                  g_arguments->prepared_rand);
304
        g_arguments->reqPerReq = g_arguments->prepared_rand;
×
305
    }
306

307
    return prepare;
20,102✔
308
}
309

310
int prepareStmt(TAOS_STMT *stmt, SSuperTable *stbInfo, char* tagData, uint64_t tableSeq, char *db) {
20,090✔
311
    char *prepare = genPrepareSql(stbInfo, tagData, tableSeq, db);
20,090✔
312
    if (taos_stmt_prepare(stmt, prepare, strlen(prepare))) {
20,078!
313
        errorPrint("taos_stmt_prepare(%s) failed. errstr=%s\n", prepare, taos_stmt_errstr(stmt));
×
314
        tmfree(prepare);
×
315
        return -1;
×
316
    }
317
    debugPrint("succ call taos_stmt_prepare sql:%s\n", prepare);
20,075!
318
    tmfree(prepare);
20,075✔
319
    return 0;
20,080✔
320
}
321

322
int prepareStmt2(TAOS_STMT2 *stmt2, SSuperTable *stbInfo, char* tagData, uint64_t tableSeq, char *db) {
26✔
323
    char *prepare = genPrepareSql(stbInfo, tagData, tableSeq, db);
26✔
324
    if (taos_stmt2_prepare(stmt2, prepare, strlen(prepare))) {
26!
325
        errorPrint("taos_stmt2_prepare(%s) failed. errstr=%s\n", prepare, taos_stmt2_error(stmt2));
×
326
        tmfree(prepare);
×
327
        return -1;
×
328
    }
329
    debugPrint("succ call taos_stmt2_prepare. sql=%s\n", prepare);
23!
330
    tmfree(prepare);
23✔
331
    return 0;
25✔
332
}
333

334

335
static bool getSampleFileNameByPattern(char *filePath,
16✔
336
                                       SSuperTable *stbInfo,
337
                                       int64_t child) {
338
    char *pos = strstr(stbInfo->childTblSample, "XXXX");
16✔
339
    snprintf(filePath, MAX_PATH_LEN, "%s", stbInfo->childTblSample);
16✔
340
    int64_t offset = (int64_t)pos - (int64_t)stbInfo->childTblSample;
16✔
341
    snprintf(filePath + offset,
16✔
342
             MAX_PATH_LEN - offset,
16✔
343
            "%s",
344
            stbInfo->childTblArray[child]->name);
16✔
345
    size_t len = strlen(stbInfo->childTblArray[child]->name);
16✔
346
    snprintf(filePath + offset + len,
16✔
347
            MAX_PATH_LEN - offset - len,
16✔
348
            "%s", pos +4);
349
    return true;
16✔
350
}
351

352
static int generateSampleFromCsv(char *buffer, char* file, FILE* fp, int32_t length, int64_t size) {
29✔
353
    size_t  n = 0;
29✔
354
    char *  line = NULL;
29✔
355
    int     getRows = 0;
29✔
356
    bool    needClose = false;
29✔
357

358
    if (file != NULL && fp == NULL) {
29!
359
        fp = fopen(file, "r");
12✔
360
        if (fp == NULL) {
12!
361
            errorPrint("open csv file failed. file=%s\n", file);
×
362
            return -1;
×
363
        }
364
        needClose = true;
12✔
365
    }
366

367
    while (1) {
59,643✔
368
        ssize_t readLen = 0;
59,672✔
369
#if defined(WIN32) || defined(WIN64)
370
        toolsGetLineFile(&line, &n, fp);
371
        readLen = n;
372
        if (0 == readLen) {
373
#else
374
        readLen = getline(&line, &n, fp);
59,672✔
375
        if (-1 == readLen) {
59,672✔
376
#endif
377
            if (0 != fseek(fp, 0, SEEK_SET)) {
7,882!
378
                errorPrint("Failed to fseek , reason:%s\n", strerror(errno));
×
379
                if(needClose)
×
380
                    fclose(fp);
×
381
                return -1;
×
382
            }
383
            continue;
7,882✔
384
        }
385

386
        int32_t pos = (int32_t)(readLen - 1);
51,790✔
387
        if(pos > 0) {
51,790!
388
            if (('\r' == line[pos]) || ('\n' == line[pos])) {
51,790!
389
                line[pos] = 0;
44,465✔
390
            }
391
        }
392
        pos = (int32_t)(readLen - 2);
51,790✔
393
        if(pos > 0) {
51,790✔
394
            if (('\r' == line[pos]) || ('\n' == line[pos])) {
51,782!
395
                line[pos] = 0;
10,175✔
396
            }
397
        }
398

399
        if (readLen == 0) {
51,790!
400
            continue;
×
401
        }
402

403
        int64_t offset = ((int64_t)getRows) * length;
51,790✔
404
        memcpy(buffer + offset, line, readLen + 1);
51,790✔
405
        getRows++;
51,790✔
406

407
        if (getRows == size) {
51,790✔
408
            break;
29✔
409
        }
410
    }
411

412
    if(needClose) {
29✔
413
        fclose(fp);
12✔
414
    }
415

416
    tmfree(line);
29✔
417
    infoPrint("read data from csv file %s, read rows=%d\n", file, getRows);
29✔
418
    return 0;
29✔
419
}
420

421
static int getAndSetRowsFromCsvFile(char *sampleFile, uint64_t *insertRows) {
10✔
422
    FILE *  fp = fopen(sampleFile, "r");
10✔
423
    if (NULL == fp) {
10!
424
        errorPrint("Failed to open sample file: %s, reason:%s\n",
×
425
                   sampleFile, strerror(errno));
426
        return -1;
×
427
    }
428

429
    int     line_count = 0;
10✔
430
    char *  buf = NULL;
10✔
431

432
    buf = benchCalloc(1, TSDB_MAX_ALLOWED_SQL_LEN, false);
10✔
433
    if (NULL == buf) {
10!
434
        errorPrint("%s() failed to allocate memory!\n", __func__);
×
435
        fclose(fp);
×
436
        return -1;
×
437
    }
438

439
    while (fgets(buf, TSDB_MAX_ALLOWED_SQL_LEN, fp)) {
96✔
440
        line_count++;
86✔
441
    }
442
    *insertRows = line_count;
10✔
443
    fclose(fp);
10✔
444
    tmfree(buf);
10✔
445
    return 0;
10✔
446
}
447

448
uint32_t accumulateRowLen(BArray *fields, int iface) {
813✔
449
    uint32_t len = 0;
813✔
450
    for (int i = 0; i < fields->size; ++i) {
52,774✔
451
        Field *field = benchArrayGet(fields, i);
51,962✔
452
        switch (field->type) {
51,962!
453
            case TSDB_DATA_TYPE_BINARY:
2,296✔
454
            case TSDB_DATA_TYPE_VARBINARY:
455
            case TSDB_DATA_TYPE_GEOMETRY:
456
            case TSDB_DATA_TYPE_NCHAR:
457
                len += field->length + 3;
2,296✔
458
                break;
2,296✔
459
            case TSDB_DATA_TYPE_INT:
40,489✔
460
            case TSDB_DATA_TYPE_UINT:
461
                len += INT_BUFF_LEN;
40,489✔
462
                break;
40,489✔
463

464
            case TSDB_DATA_TYPE_BIGINT:
1,411✔
465
            case TSDB_DATA_TYPE_UBIGINT:
466
                len += BIGINT_BUFF_LEN;
1,411✔
467
                break;
1,411✔
468

469
            case TSDB_DATA_TYPE_SMALLINT:
2,572✔
470
            case TSDB_DATA_TYPE_USMALLINT:
471
                len += SMALLINT_BUFF_LEN;
2,572✔
472
                break;
2,572✔
473

474
            case TSDB_DATA_TYPE_TINYINT:
1,050✔
475
            case TSDB_DATA_TYPE_UTINYINT:
476
                len += TINYINT_BUFF_LEN;
1,050✔
477
                break;
1,050✔
478

479
            case TSDB_DATA_TYPE_BOOL:
1,241✔
480
                len += BOOL_BUFF_LEN;
1,241✔
481
                break;
1,241✔
482

483
            case TSDB_DATA_TYPE_FLOAT:
1,452✔
484
                len += FLOAT_BUFF_LEN;
1,452✔
485
                break;
1,452✔
486

487
            case TSDB_DATA_TYPE_DOUBLE:
1,399✔
488
                len += DOUBLE_BUFF_LEN;
1,399✔
489
                break;
1,399✔
490

491
            case TSDB_DATA_TYPE_DECIMAL:
10✔
492
                len += DECIMAL_BUFF_LEN;
10✔
493
                break;
10✔
494

495
            case TSDB_DATA_TYPE_DECIMAL64:
10✔
496
                len += DECIMAL64_BUFF_LEN;
10✔
497
                break;
10✔
498

499
            case TSDB_DATA_TYPE_TIMESTAMP:
31✔
500
                len += TIMESTAMP_BUFF_LEN;
31✔
501
                break;
31✔
502
            case TSDB_DATA_TYPE_JSON:
1✔
503
                len += field->length * fields->size;
1✔
504
                return len;
1✔
505
        }
506
        len += 1;
51,961✔
507
        if (iface == SML_REST_IFACE || iface == SML_IFACE) {
51,961✔
508
            len += SML_LINE_SQL_SYNTAX_OFFSET + strlen(field->name);
1,402✔
509
        }
510
    }
511
    if (iface == SML_IFACE || iface == SML_REST_IFACE) {
812✔
512
        len += 2 * TSDB_TABLE_NAME_LEN * 2 + SML_LINE_SQL_SYNTAX_OFFSET;
213✔
513
    }
514
    len += TIMESTAMP_BUFF_LEN;
812✔
515
    return len;
812✔
516
}
517

518

519
int tmpStr(char *tmp, int iface, Field *field, int64_t k) {
39,057,805✔
520
    if (field->values) {
39,057,805✔
521
        int arraySize = tools_cJSON_GetArraySize(field->values);
11,460✔
522
        if (arraySize) {
11,460!
523
            tools_cJSON *buf = tools_cJSON_GetArrayItem(
11,460✔
524
                    field->values,
11,460✔
525
                    taosRandom() % arraySize);
11,460✔
526
            snprintf(tmp, field->length,
11,460✔
527
                     "%s", buf->valuestring);
528
        } else {
529
            errorPrint("%s() cannot read correct value "
×
530
                       "from json file. array size: %d\n",
531
                       __func__, arraySize);
532
            return -1;
×
533
        }
534
    } else if (g_arguments->demo_mode) {
39,046,345✔
535
        unsigned int tmpRand = taosRandom();
60,509✔
536
        if (g_arguments->chinese) {
60,511!
537
            snprintf(tmp, field->length, "%s",
×
538
                     locations_chinese[tmpRand % 10]);
×
539
        } else if (SML_IFACE == iface) {
60,511✔
540
            snprintf(tmp, field->length, "%s",
13✔
541
                     locations_sml[tmpRand % 10]);
13✔
542
        } else {
543
            snprintf(tmp, field->length, "%s",
60,498✔
544
                     locations[tmpRand % 10]);
60,498✔
545
        }
546
    } else {
547
        if(field->gen == GEN_ORDER) {
38,985,836✔
548
            snprintf(tmp, field->length, "%"PRId64, k);
978,817✔
549
        } else {
550
            rand_string(tmp, taosRandom() % field->length, g_arguments->chinese);
38,007,019✔
551
        }
552
    }
553
    return 0;
39,063,903✔
554
}
555

556
int tmpGeometry(char *tmp, int iface, Field *field, int64_t k) {
100,700✔
557
    // values
558
    if (field->values) {
100,700!
559
        int arraySize = tools_cJSON_GetArraySize(field->values);
×
560
        if (arraySize) {
×
561
            tools_cJSON *buf = tools_cJSON_GetArrayItem(
×
562
                    field->values,
×
563
                    taosRandom() % arraySize);
×
564
            snprintf(tmp, field->length,
×
565
                     "%s", buf->valuestring);
566
        } else {
567
            errorPrint("%s() cannot read correct value "
×
568
                       "from json file. array size: %d\n",
569
                       __func__, arraySize);
570
            return -1;
×
571
        }
572
        return 0;
×
573
    }
574

575
    // gen point count
576
    int32_t cnt = field->length / 24;
100,700✔
577
    if(cnt < 2) {
100,700✔
578
        snprintf(tmp, field->length, "POINT(%d %d)", tmpUint16(field), tmpUint16(field));
60,300✔
579
        return 0;
60,300✔
580
    }
581
    
582
    int32_t pos = snprintf(tmp, field->length, "LINESTRING(");
40,400✔
583
    char * format = "%d %d,";
40,400✔
584
    for(int32_t i = 0; i < cnt; i++) {
121,199✔
585
        if (i == cnt - 1) {
80,799✔
586
            format = "%d %d";
40,400✔
587
        } 
588
        pos += snprintf(tmp + pos, field->length - pos, format, tmpUint16(field), tmpUint16(field));
80,799✔
589
    }
590
    strcat(tmp, ")");
40,400✔
591

592
    return 0;
40,400✔
593
}
594

595
bool tmpBool(Field *field) {
24,554,630✔
596
    bool boolTmp;
597
    if (field->min == field->max) {
24,554,630✔
598
        boolTmp = (field->min)?1:0;
3,623✔
599
    } else {
600
        boolTmp = (taosRandom() % 2)&1;
24,551,007✔
601
    }
602
    return boolTmp;
24,556,237✔
603
}
604

605
int8_t tmpInt8Impl(Field *field, int64_t k) {
14,833,512✔
606
    int8_t tinyint = field->min;
14,833,512✔
607
    if (field->min != field->max) {
14,833,512✔
608
        tinyint += COL_GEN % (field->max - field->min);
14,829,846✔
609
    }
610
    return tinyint;
14,834,943✔
611
}
612

613
uint8_t tmpUint8Impl(Field *field, int64_t k) {
4,676,086✔
614
    uint8_t utinyint = field->min;
4,676,086✔
615
    if (field->min != field->max) {
4,676,086✔
616
        utinyint += (COL_GEN % (field->max - field->min));
4,672,492✔
617
    }
618
    return utinyint;
4,676,729✔
619
}
620

621
int16_t tmpInt16Impl(Field *field, int64_t k) {
41,405,269✔
622
    int16_t smallint = field->min;
41,405,269✔
623
    if (field->min != field->max) {
41,405,269✔
624
        smallint += (COL_GEN % (field->max - field->min));
41,401,673✔
625
    }
626
    return smallint;
41,406,647✔
627
}
628

629
uint16_t tmpUint16Impl(Field *field, int64_t k) {
4,657,544✔
630
    uint16_t usmallintTmp = field->min;
4,657,544✔
631
    if (field->max != field->min) {
4,657,544✔
632
        usmallintTmp += (COL_GEN % (field->max - field->min));
4,653,941✔
633
    }
634
    return usmallintTmp;
4,658,163✔
635
}
636

637
int tmpInt32Impl(Field *field, int i, int angle, int32_t k) {
916,181,225✔
638
    int intTmp;
639
    if (field->funType != FUNTYPE_NONE) {
916,181,225✔
640
        // calc from function
641
        intTmp = funValueInt32(field, angle, k);
1,452,814✔
642
    } else if ((g_arguments->demo_mode) && (i == 0)) {
914,728,411!
643
        unsigned int tmpRand = taosRandom();
60,473✔
644
        intTmp = tmpRand % 10 + 1;
60,499✔
645
    } else if ((g_arguments->demo_mode) && (i == 1)) {
914,667,938!
646
        intTmp = 105 + taosRandom() % 10;
×
647
    } else {
648
        if (field->min < (-1 * (RAND_MAX >> 1))) {
914,667,938!
649
            field->min = -1 * (RAND_MAX >> 1);
×
650
        }
651
        if (field->max > (RAND_MAX >> 1)) {
914,667,938!
652
            field->max = RAND_MAX >> 1;
×
653
        }
654
        intTmp = field->min;
914,667,938✔
655
        if (field->max != field->min) {
914,667,938✔
656
            intTmp += (COL_GEN % (field->max - field->min));
914,580,514✔
657
        }
658
    }
659
    return intTmp;
916,508,988✔
660
}
661

662
int tmpInt32ImplTag(Field *field, int i, int k) {
54✔
663
    int intTmp;
664

665
    if (field->min < (-1 * (RAND_MAX >> 1))) {
54!
666
        field->min = -1 * (RAND_MAX >> 1);
×
667
    }
668
    if (field->max > (RAND_MAX >> 1)) {
54!
669
        field->max = RAND_MAX >> 1;
×
670
    }
671
    intTmp = field->min;
54✔
672
    if (field->max != field->min) {
54!
673
        intTmp += (COL_GEN % (field->max - field->min));
54!
674
    }
675
    return intTmp;
54✔
676
}
677

678

679
uint32_t tmpUint32Impl(Field *field, int i, int angle, int64_t k) {
4,559,716✔
680
    uint32_t intTmp;
681
    if (field->funType != FUNTYPE_NONE) {
4,559,716!
682
        // calc from function
683
        intTmp = funValueInt32(field, angle, k);
×
684
    } else if ((g_arguments->demo_mode) && (i == 0)) {
4,559,716!
685
        unsigned int tmpRand = taosRandom();
×
686
        intTmp = tmpRand % 10 + 1;
×
687
    } else if ((g_arguments->demo_mode) && (i == 1)) {
4,559,716!
688
        intTmp = 105 + taosRandom() % 10;
×
689
    } else {
690
        intTmp = field->min;
4,559,716✔
691
        if (field->max != field->min) {
4,559,716✔
692
            intTmp += (COL_GEN % (field->max - field->min));
4,555,661✔
693
        }
694
    }
695
    return intTmp;
4,560,398✔
696
}
697

698
int64_t tmpInt64Impl(Field *field, int32_t angle, int32_t k) {
84,431,881✔
699
    int64_t bigintTmp = field->min;
84,431,881✔
700
    if(field->funType != FUNTYPE_NONE) {
84,431,881!
701
        bigintTmp = funValueInt32(field, angle, k);
×
702
    } else if (field->min != field->max) {
84,431,881!
703
        bigintTmp += (COL_GEN % (field->max - field->min));
84,520,161✔
704
    }
705
    return bigintTmp;
84,417,322✔
706
}
707

708
uint64_t tmpUint64Impl(Field *field, int32_t angle, int64_t k) {
4,525,538✔
709
    uint64_t bigintTmp = field->min;
4,525,538✔
710
    if(field->funType != FUNTYPE_NONE) {
4,525,538!
711
        bigintTmp = funValueInt32(field, angle, k);
×
712
    } else if (field->min != field->max) {
4,525,538✔
713
        bigintTmp += (COL_GEN % (field->max - field->min));
4,521,976✔
714
    }
715
    return bigintTmp;
4,526,364✔
716
}
717

718
float tmpFloatImpl(Field *field, int i, int32_t angle, int32_t k) {
28,113,538✔
719
    float floatTmp = (float)field->min;
28,113,538✔
720
    if(field->funType != FUNTYPE_NONE) {
28,113,538✔
721
        floatTmp = funValueFloat(field, angle, k);
2,925,632✔
722
    } else {
723
        if (field->max != field->min) {
25,187,906✔
724
            if (field->gen == GEN_ORDER) {
25,181,364✔
725
                floatTmp += (k % (field->max - field->min));
968,679✔
726
            } else {
727
                floatTmp += ((taosRandom() %
24,212,685✔
728
                        (field->max - field->min))
24,213,439✔
729
                    + (taosRandom() % 1000) / 1000.0);
24,213,439✔
730
            }
731
        }
732
        if (g_arguments->demo_mode && i == 0) {
25,188,798!
733
            floatTmp = (float)(9.8 + 0.04 * (taosRandom() % 10)
×
734
                + floatTmp / 1000000000);
×
735
        } else if (g_arguments->demo_mode && i == 2) {
25,188,798!
736
            floatTmp = (float)((105 + taosRandom() % 10
×
737
                + floatTmp / 1000000000) / 360);
×
738
        }
739
    }
740

741
    if (field->scalingFactor > 0) {
28,113,549✔
742
        if (field->scalingFactor > 1)
25,067,819✔
743
            floatTmp = floatTmp / field->scalingFactor;
3,398,915✔
744

745
        if (floatTmp > field->maxInDbl)
25,067,819!
746
            floatTmp = field->maxInDbl;
×
747
        else if (floatTmp < field->minInDbl)
25,067,819!
748
            floatTmp = field->minInDbl;
×
749
    }
750

751
    return floatTmp;
28,113,549✔
752
}
753

754
double tmpDoubleImpl(Field *field, int32_t angle, int32_t k) {
27,326,773✔
755
    double doubleTmp = (double)(field->min);
27,326,773✔
756
    if(field->funType != FUNTYPE_NONE) {
27,326,773!
757
        doubleTmp = funValueFloat(field, angle, k);
×
758
    } else if (field->max != field->min) {
27,326,773✔
759
        if(field->gen == GEN_ORDER) {
27,205,815✔
760
            doubleTmp += k % (field->max - field->min);
967,929✔
761
        } else {
762
            doubleTmp += ((taosRandom() %
26,237,886✔
763
                (field->max - field->min)) +
52,477,110✔
764
                taosRandom() % 1000000 / 1000000.0);
26,238,440✔
765
        }
766
    }
767

768
    if (field->scalingFactor > 0) {
27,327,557✔
769
        if (field->scalingFactor > 1) {
27,207,146✔
770
            doubleTmp /= field->scalingFactor;
2,957,495✔
771
        }
772

773
        if (doubleTmp > field->maxInDbl)
27,207,146!
774
            doubleTmp = field->maxInDbl;
×
775
        else if (doubleTmp < field->minInDbl)
27,207,146!
776
            doubleTmp = field->minInDbl;
×
777
    }
778

779
    return doubleTmp;
27,327,557✔
780
}
781

782
static int tmpJson(char *sampleDataBuf,
800✔
783
                   int bufLen, int64_t pos,
784
                   int fieldsSize, Field *field) {
785
    int n = snprintf(sampleDataBuf + pos, bufLen - pos, "'{");
800✔
786
    if (n < 0 || n >= bufLen - pos) {
800!
787
        errorPrint("%s() LN%d snprintf overflow\n",
×
788
                   __func__, __LINE__);
789
        return -1;
×
790
    }
791
    for (int j = 0; j < fieldsSize; ++j) {
1,600✔
792
        // key
793
        n += snprintf(sampleDataBuf + pos + n, bufLen - pos - n,
800✔
794
                        "\"k%d\":", j);
795
        if (n < 0 || n >= bufLen - pos) {
800!
796
            errorPrint("%s() LN%d snprintf overflow\n",
×
797
                       __func__, __LINE__);
798
            return -1;
×
799
        }
800
        // value
801
        char *buf = benchCalloc(1, field->length + 1, false);
800✔
802
        rand_string(buf, 12, g_arguments->chinese);
800✔
803
        n += snprintf(sampleDataBuf + pos + n, bufLen - pos - n,
800✔
804
                        "\"%s\",", buf);
805
        if (n < 0 || n >= bufLen - pos) {
800!
806
            errorPrint("%s() LN%d snprintf overflow\n",
×
807
                       __func__, __LINE__);
808
            tmfree(buf);
×
809
            return -1;
×
810
        }
811
        tmfree(buf);
800✔
812
    }
813
    n += snprintf(sampleDataBuf + pos + n - 1,
800✔
814
                    bufLen - pos - n, "}'");
800✔
815
    if (n < 0 || n >= bufLen - pos) {
800!
816
        errorPrint("%s() LN%d snprintf overflow\n",
×
817
                   __func__, __LINE__);
818
        return -1;
×
819
    }
820

821
    return n;
800✔
822
}
823

824

825
static uint64_t generateRandomUint64(uint64_t range) {
447,454✔
826
    uint64_t randomValue;
827

828
    if (range <= (uint64_t)RAND_MAX) {
447,454✔
829
        randomValue = (uint64_t)rand() % range;
260,000✔
830
    } else {
831
        int bitsPerRand = 0;
187,454✔
832
        for (uint64_t r = RAND_MAX; r > 0; r >>= 1) {
5,998,528✔
833
            bitsPerRand++;
5,811,074✔
834
        }
835

836
        uint64_t result;
837
        uint64_t threshold;
838

839
        do {
840
            result = 0;
228,188✔
841
            int bitsAccumulated = 0;
228,188✔
842

843
            while (bitsAccumulated < 64) {
912,752✔
844
                uint64_t part = (uint64_t)rand();
684,564✔
845
                int bits = (64 - bitsAccumulated) < bitsPerRand ? (64 - bitsAccumulated) : bitsPerRand;
684,564✔
846
                part &= (1ULL << bits) - 1;
684,564✔
847
                result |= part << bitsAccumulated;
684,564✔
848
                bitsAccumulated += bits;
684,564✔
849
            }
850

851
            // rejecting sample
852
            threshold = (UINT64_MAX / range) * range;
228,188✔
853
            threshold = (threshold == 0) ? 0 : threshold - 1;
228,188!
854

855
        } while (result > threshold);
228,188✔
856

857
        randomValue = result % range;
187,454✔
858
    }
859

860
    return randomValue;
447,454✔
861
}
862

863

864
static uint64_t randUint64(uint64_t min, uint64_t max) {
200,000✔
865
    if (min >= max || (max - min) == UINT64_MAX) {
200,000!
866
        return min;
112,546✔
867
    }
868

869
    uint64_t range = max - min + 1;
87,454✔
870
    return min + generateRandomUint64(range);
87,454✔
871
}
872

873

874
static int64_t randInt64(int64_t min, int64_t max) {
400,000✔
875
    if (min >= max || ((uint64_t)max - (uint64_t)min) == UINT64_MAX) {
400,000!
876
        return min;
40,000✔
877
    }
878

879
    uint64_t range = (uint64_t)max - (uint64_t)min + 1;
360,000✔
880
    return (int64_t)(min + generateRandomUint64(range));
360,000✔
881
}
882

883

884
static void decimal64Rand(Decimal64* result, const Decimal64* min, const Decimal64* max) {
200,000✔
885
    int64_t temp = 0;
200,000✔
886
    
887
    do {
888
        temp = randInt64(DECIMAL64_GET_VALUE(min), DECIMAL64_GET_VALUE(max));
200,000✔
889
    } while (temp < DECIMAL64_GET_VALUE(min) || temp > DECIMAL64_GET_VALUE(max));
200,000!
890

891
    DECIMAL64_SET_VALUE(result, temp);
200,000✔
892
}
200,000✔
893

894

895
static void decimal128Rand(Decimal128* result, const Decimal128* min, const Decimal128* max) {
200,000✔
896
    int64_t  high   = 0;
200,000✔
897
    uint64_t low    = 0;
200,000✔
898
    Decimal128 temp = {0};
200,000✔
899

900
    int64_t minHigh = DECIMAL128_HIGH_WORD(min);
200,000✔
901
    int64_t maxHigh = DECIMAL128_HIGH_WORD(max);
200,000✔
902
    uint64_t minLow = DECIMAL128_LOW_WORD(min);
200,000✔
903
    uint64_t maxLow = DECIMAL128_LOW_WORD(max);
200,000✔
904

905
    do {
906
        // high byte
907
        high = randInt64(minHigh, maxHigh);
200,000✔
908

909
        // low byte
910
        if (high == minHigh && high == maxHigh) {
200,000✔
911
            low = randUint64(minLow, maxLow);   
40,000✔
912
        } else if (high == minHigh) {
160,000✔
913
            low = randUint64(minLow, UINT64_MAX);
23,601✔
914
        } else if (high == maxHigh) {
136,399✔
915
            low = randUint64(0, maxLow);
23,853✔
916
        } else {
917
            low = randUint64(0, UINT64_MAX);
112,546✔
918
        }
919

920
        DECIMAL128_SET_HIGH_WORD(&temp, high);
200,000✔
921
        DECIMAL128_SET_LOW_WORD(&temp, low);
200,000✔
922

923
    } while (decimal128BCompare(&temp, min) < 0 || decimal128BCompare(&temp, max) > 0);
200,000!
924

925
    *result = temp;
200,000✔
926
}
200,000✔
927

928

929
Decimal64 tmpDecimal64Impl(Field* field, int32_t angle, int32_t k) {
200,000✔
930
    (void)angle;
931
    (void)k;
932

933
    Decimal64 result = {0};
200,000✔
934
    decimal64Rand(&result, &field->decMin.dec64, &field->decMax.dec64);
200,000✔
935
    return result;
200,000✔
936
}
937

938

939
Decimal128 tmpDecimal128Impl(Field* field, int32_t angle, int32_t k) {
200,000✔
940
    (void)angle;
941
    (void)k;
942

943
    Decimal128 result = {0};
200,000✔
944
    decimal128Rand(&result, &field->decMin.dec128, &field->decMax.dec128);
200,000✔
945
    return result;
200,000✔
946
}
947

948

949
static int generateRandDataSQL(SSuperTable *stbInfo, char *sampleDataBuf,
1,684✔
950
                     int64_t bufLen,
951
                      int lenOfOneRow, BArray * fields, int64_t loop,
952
                      bool tag, int64_t loopBegin) {
953
                        
954
    int64_t index = loopBegin;
1,684✔
955
    int angle = stbInfo->startTimestamp % 360; // 0 ~ 360
1,684✔
956
    for (int64_t k = 0; k < loop; ++k, ++index) {
4,332,669✔
957
        int64_t pos = k * lenOfOneRow;
4,330,934✔
958
        int fieldsSize = fields->size;
4,330,934✔
959
        for (int i = 0; i < fieldsSize; ++i) {
965,472,410✔
960
            Field * field = benchArrayGet(fields, i);
961,142,225✔
961
            if (field->none) {
961,142,202✔
962
                continue;
21,830✔
963
            }
964

965
            int n = 0;
961,120,372✔
966
            if (field->null) {
961,120,372✔
967
                n = snprintf(sampleDataBuf + pos, bufLen - pos, "null,");
10✔
968
                if (n < 0 || n >= bufLen - pos) {
10!
969
                    errorPrint("%s() LN%d snprintf overflow\n",
×
970
                               __func__, __LINE__);
971
                    return -1;
×
972
                } else {
973
                    pos += n;
10✔
974
                    continue;
10✔
975
                }
976
            }
977
            switch (field->type) {
961,120,362!
978
                case TSDB_DATA_TYPE_BOOL: {
20,702,349✔
979
                    bool boolTmp = tmpBool(field);
20,702,349✔
980
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
20,702,350✔
981
                                    "%s,", boolTmp ? "true" : "false");
982
                    break;
20,702,350✔
983
                }
984
                case TSDB_DATA_TYPE_TINYINT: {
10,897,548✔
985
                    int8_t tinyint = tmpInt8Impl(field, index);
10,897,548✔
986
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
10,897,549✔
987
                                    "%d,", tinyint);
988
                    break;
10,897,549✔
989
                }
990
                case TSDB_DATA_TYPE_UTINYINT: {
824,732✔
991
                    uint8_t utinyint = tmpUint8Impl(field, index);
824,732✔
992
                    n = snprintf(sampleDataBuf + pos,
824,737✔
993
                                    bufLen - pos, "%u,", utinyint);
824,737✔
994
                    break;
824,737✔
995
                }
996
                case TSDB_DATA_TYPE_SMALLINT: {
30,524,937✔
997
                    int16_t smallint = tmpInt16Impl(field, index);
30,524,937✔
998
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
30,524,939✔
999
                                        "%d,", smallint);
1000
                    break;
30,524,939✔
1001
                }
1002
                case TSDB_DATA_TYPE_USMALLINT: {
522,838✔
1003
                    uint16_t usmallint = tmpUint16Impl(field, index);
522,838✔
1004
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
522,840✔
1005
                                        "%u,", usmallint);
1006
                    break;
522,840✔
1007
                }
1008
                case TSDB_DATA_TYPE_INT: {
798,081,517✔
1009
                    int32_t intTmp = tmpInt32Impl(field, i, angle, index);
798,081,517✔
1010
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
798,081,539✔
1011
                                        "%d,", intTmp);
1012
                    break;
798,081,539✔
1013
                }
1014
                case TSDB_DATA_TYPE_BIGINT: {
21,262,548✔
1015
                    int64_t bigintTmp = tmpInt64Impl(field, angle, index);
21,262,548✔
1016
                    n = snprintf(sampleDataBuf + pos,
21,262,550✔
1017
                                 bufLen - pos, "%"PRId64",", bigintTmp);
21,262,550✔
1018
                    break;
21,262,550✔
1019
                }
1020
                case TSDB_DATA_TYPE_UINT: {
706,889✔
1021
                    uint32_t uintTmp = tmpUint32Impl(field, i, angle, index);
706,889✔
1022
                    n = snprintf(sampleDataBuf + pos,
706,888✔
1023
                                 bufLen - pos, "%u,", uintTmp);
706,888✔
1024
                    break;
706,888✔
1025
                }
1026
                case TSDB_DATA_TYPE_UBIGINT:
650,507✔
1027
                case TSDB_DATA_TYPE_TIMESTAMP: {
1028
                    uint64_t ubigintTmp = tmpUint64Impl(field, angle, index);
650,507✔
1029
                    n = snprintf(sampleDataBuf + pos,
650,514✔
1030
                                 bufLen - pos, "%"PRIu64",", ubigintTmp);
650,514✔
1031
                    break;
650,514✔
1032
                }
1033
                case TSDB_DATA_TYPE_FLOAT: {
23,387,368✔
1034
                    float floatTmp = tmpFloatImpl(field, i, angle, index);
23,387,368✔
1035
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
23,387,369✔
1036
                                        "%f,", floatTmp);
1037
                    break;
23,387,369✔
1038
                }
1039
                case TSDB_DATA_TYPE_DOUBLE: {
22,588,344✔
1040
                    double double_ =  tmpDoubleImpl(field, angle, index);
22,588,344✔
1041
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
22,588,348✔
1042
                                        "%f,", double_);
1043
                    break;
22,588,348✔
1044
                }
1045
                case TSDB_DATA_TYPE_DECIMAL: {
200,000✔
1046
                    Decimal128 dec = tmpDecimal128Impl(field, angle, index);
200,000✔
1047
                    int ret = decimal128ToString(&dec, field->precision, field->scale, sampleDataBuf + pos, bufLen - pos);
200,000✔
1048
                    if (ret != 0) {
200,000!
1049
                        errorPrint("%s() LN%d precision: %d, scale: %d, high: %" PRId64 ", low: %" PRIu64 "\n",
×
1050
                                __func__, __LINE__, field->precision, field->scale, DECIMAL128_HIGH_WORD(&dec), DECIMAL128_LOW_WORD(&dec));
1051
                        return -1;
×
1052
                    }
1053
                    size_t decLen = strlen(sampleDataBuf + pos);
200,000✔
1054
                    n = snprintf(sampleDataBuf + pos + decLen, bufLen - pos - decLen, ",");
200,000✔
1055
                    n += decLen;
200,000✔
1056
                    break;
200,000✔
1057
                }
1058
                case TSDB_DATA_TYPE_DECIMAL64: {
200,000✔
1059
                    Decimal64 dec = tmpDecimal64Impl(field, angle, index);
200,000✔
1060
                    int ret = decimal64ToString(&dec, field->precision, field->scale, sampleDataBuf + pos, bufLen - pos);
200,000✔
1061
                    if (ret != 0) {
200,000!
1062
                        errorPrint("%s() LN%d precision: %d, scale: %d, value: %" PRId64 "\n",
×
1063
                                __func__, __LINE__, field->precision, field->scale, DECIMAL64_GET_VALUE(&dec));
1064
                        return -1;
×
1065
                    }
1066
                    size_t decLen = strlen(sampleDataBuf + pos);
200,000✔
1067
                    n = snprintf(sampleDataBuf + pos + decLen, bufLen - pos - decLen, ",");
200,000✔
1068
                    n += decLen;
200,000✔
1069
                    break;
200,000✔
1070
                }
1071
                case TSDB_DATA_TYPE_BINARY:
30,490,077✔
1072
                case TSDB_DATA_TYPE_VARBINARY:
1073
                case TSDB_DATA_TYPE_NCHAR: {
1074
                    char *tmp = benchCalloc(1, field->length + 1, false);
30,490,077✔
1075
                    if (0 != tmpStr(tmp, stbInfo->iface, field, index)) {
30,490,085!
1076
                        free(tmp);
×
1077
                        return -1;
×
1078
                    }
1079
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
30,490,082✔
1080
                                        "'%s',", tmp);
1081
                    tmfree(tmp);
30,490,082✔
1082
                    break;
30,490,081✔
1083
                }
1084
                case TSDB_DATA_TYPE_GEOMETRY: {
80,500✔
1085
                    int   bufferSize = field->length + 1;
80,500✔
1086
                    char *tmp = benchCalloc(1, bufferSize, false);
80,500✔
1087
                    if (0 != tmpGeometry(tmp, stbInfo->iface, field, i)) {
80,500!
1088
                        free(tmp);
×
1089
                        return -1;
×
1090
                    }
1091
                    n = snprintf(sampleDataBuf + pos, bufLen - pos, "'%s',", tmp);
80,500✔
1092
                    tmfree(tmp);
80,500✔
1093
                    break;
80,500✔
1094
                }
1095
                case TSDB_DATA_TYPE_JSON: {
800✔
1096
                    n = tmpJson(sampleDataBuf, bufLen, pos, fieldsSize, field);
800✔
1097
                    if (n == -1) {
800!
1098
                        return -1;
×
1099
                    }
1100
                    pos += n;
800✔
1101
                    goto skip_sql;
800✔
1102
                }
1103
            }
1104
            if (TSDB_DATA_TYPE_JSON != field->type) {
961,119,612!
1105
                if (n < 0 || n >= bufLen - pos) {
961,119,618!
1106
                    errorPrint("%s() LN%d snprintf overflow\n",
×
1107
                               __func__, __LINE__);
1108
                    return -1;
×
1109
                } else {
1110
                    pos += n;
961,119,642✔
1111
                }
1112
            }
1113
        }
1114
skip_sql:
4,330,185✔
1115
        *(sampleDataBuf + pos - 1) = 0;
4,330,985✔
1116
        angle += stbInfo->timestamp_step/stbInfo->angle_step;
4,330,985✔
1117
        if (angle > 360) {
4,330,985✔
1118
            angle -= 360;
1,174,069✔
1119
        }
1120
}
1121

1122
    return 0;
1,735✔
1123
}
1124

1125
static int fillStmt(
671✔
1126
    SSuperTable *stbInfo,
1127
    char *sampleDataBuf,
1128
    int64_t bufLen,
1129
    int lenOfOneRow, BArray *fields,
1130
    int64_t loop, bool tag, BArray *childCols, int64_t loopBegin) {
1131
    int angle = stbInfo->startTimestamp % 360; // 0 ~ 360
671✔
1132
    debugPrint("fillStml stbname=%s loop=%"PRId64" istag=%d  fieldsSize=%d\n", stbInfo->stbName, loop, tag, (int32_t)fields->size);
671!
1133
    int64_t index = loopBegin;
671✔
1134
    for (int64_t k = 0; k < loop; ++k, ++index) {
506,243✔
1135
        int64_t pos = k * lenOfOneRow;
505,564✔
1136
        char* line = sampleDataBuf + pos;
505,564✔
1137
        int fieldsSize = fields->size;
505,564✔
1138
        for (int i = 0; i < fieldsSize; ++i) {
10,968,195✔
1139
            Field * field = benchArrayGet(fields, i);
10,462,476✔
1140
            ChildField *childCol = NULL;
10,462,434✔
1141
            if (childCols) {
10,462,434✔
1142
                childCol = benchArrayGet(childCols, i);
8,442✔
1143
            }
1144
            int64_t n = 0;
10,462,434✔
1145

1146
            // 
1147
            if (childCol) {
10,462,434✔
1148
                childCol->stmtData.is_null[k] = 0;
8,442✔
1149
                childCol->stmtData.lengths[k] = field->length;
8,442✔
1150
            } else {
1151
                field->stmtData.is_null[k] = 0;
10,453,992✔
1152
                field->stmtData.lengths[k] = field->length;
10,453,992✔
1153
            }
1154

1155
            switch (field->type) {
10,462,434!
1156
                case TSDB_DATA_TYPE_BOOL: {
63,120✔
1157
                    bool boolTmp = tmpBool(field);
63,120✔
1158
                    if (childCol) {
63,120!
1159
                        ((bool *)childCol->stmtData.data)[k] = boolTmp;
×
1160
                    } else {
1161
                        ((bool *)field->stmtData.data)[k] = boolTmp;
63,120✔
1162
                    }
1163
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
63,120✔
1164
                                 "%d,", boolTmp);
1165
                    break;
63,120✔
1166
                }
1167
                case TSDB_DATA_TYPE_TINYINT: {
148,319✔
1168
                    int8_t tinyintTmp = tmpInt8Impl(field, index);
148,319✔
1169
                    if (childCol) {
148,319!
1170
                        ((int8_t *)childCol->stmtData.data)[k] = tinyintTmp;
×
1171
                    } else {
1172
                        ((int8_t *)field->stmtData.data)[k] = tinyintTmp;
148,319✔
1173
                    }
1174
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
148,319✔
1175
                                 "%d,", tinyintTmp);
1176
                    break;
148,319✔
1177
                }
1178
                case TSDB_DATA_TYPE_UTINYINT: {
63,119✔
1179
                    uint8_t utinyintTmp = tmpUint8Impl(field, index);
63,119✔
1180
                    if (childCol) {
63,118!
1181
                        ((uint8_t *)childCol->stmtData.data)[k] = utinyintTmp;
×
1182
                    } else {
1183
                        ((uint8_t *)field->stmtData.data)[k] = utinyintTmp;
63,118✔
1184
                    }
1185
                    n = snprintf(sampleDataBuf + pos,
63,118✔
1186
                                 bufLen - pos, "%u,", utinyintTmp);
63,118✔
1187
                    break;
63,118✔
1188
                }
1189
                case TSDB_DATA_TYPE_SMALLINT: {
7,093,114✔
1190
                    int16_t smallintTmp = tmpInt16Impl(field, index);
7,093,114✔
1191
                    if (childCol) {
7,093,120!
1192
                        ((int16_t *)childCol->stmtData.data)[k] = smallintTmp;
×
1193
                    } else {
1194
                        ((int16_t *)field->stmtData.data)[k] = smallintTmp;
7,093,120✔
1195
                    }
1196
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
7,093,120✔
1197
                                        "%d,", smallintTmp);
1198
                    break;
7,093,120✔
1199
                }
1200
                case TSDB_DATA_TYPE_USMALLINT: {
64,312✔
1201
                    uint16_t usmallintTmp = tmpUint16Impl(field, index);
64,312✔
1202
                    if (childCol) {
64,320!
1203
                        ((uint16_t *)childCol->stmtData.data)[k] = usmallintTmp;
×
1204
                    } else {
1205
                        ((uint16_t *)field->stmtData.data)[k] = usmallintTmp;
64,320✔
1206
                    }
1207
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
64,320✔
1208
                                        "%u,", usmallintTmp);
1209
                    break;
64,320✔
1210
                }
1211
                case TSDB_DATA_TYPE_INT: {
389,008✔
1212
                    int32_t intTmp = tmpInt32Impl(field, i, angle, index);
389,008✔
1213
                    if (childCol) {
389,119✔
1214
                        ((int32_t *)childCol->stmtData.data)[k] = intTmp;
2,814✔
1215
                    } else {
1216
                        ((int32_t *)field->stmtData.data)[k] = intTmp;
386,305✔
1217
                    }
1218
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
389,119✔
1219
                                        "%d,", intTmp);
1220
                    break;
389,119✔
1221
                }
1222
                case TSDB_DATA_TYPE_BIGINT: {
63,117✔
1223
                    int64_t bigintTmp = tmpInt64Impl(field, angle, index);
63,117✔
1224
                    if (childCol) {
63,119!
1225
                        ((int64_t *)childCol->stmtData.data)[k] = bigintTmp;
×
1226
                    } else {
1227
                        ((int64_t *)field->stmtData.data)[k] = bigintTmp;
63,119✔
1228
                    }
1229
                    n = snprintf(sampleDataBuf + pos,
63,119✔
1230
                                 bufLen - pos, "%"PRId64",", bigintTmp);
63,119✔
1231
                    break;
63,119✔
1232
                }
1233
                case TSDB_DATA_TYPE_UINT: {
64,418✔
1234
                    uint32_t uintTmp = tmpUint32Impl(field, i, angle, index);
64,418✔
1235
                    if (childCol) {
64,420!
1236
                        ((uint32_t *)childCol->stmtData.data)[k] = uintTmp;
×
1237
                    } else {
1238
                        ((uint32_t *)field->stmtData.data)[k] = uintTmp;
64,420✔
1239
                    }
1240
                    n = snprintf(sampleDataBuf + pos,
64,420✔
1241
                                 bufLen - pos, "%u,", uintTmp);
64,420✔
1242
                    break;
64,420✔
1243
                }
1244
                case TSDB_DATA_TYPE_UBIGINT:
87,417✔
1245
                case TSDB_DATA_TYPE_TIMESTAMP: {
1246
                    uint64_t ubigintTmp = tmpUint64Impl(field, angle, index);
87,417✔
1247
                    if (childCol) {
87,426!
1248
                        ((uint64_t *)childCol->stmtData.data)[k] = ubigintTmp;
×
1249
                    } else {
1250
                        ((uint64_t *)field->stmtData.data)[k] = ubigintTmp;
87,426✔
1251
                    }
1252
                    n = snprintf(sampleDataBuf + pos,
87,426✔
1253
                                 bufLen - pos, "%"PRIu64",", ubigintTmp);
87,426✔
1254
                    break;
87,426✔
1255
                }
1256
                case TSDB_DATA_TYPE_FLOAT: {
458,741✔
1257
                    float floatTmp = tmpFloatImpl(field, i, angle, index);
458,741✔
1258
                    if (childCol) {
458,747✔
1259
                        ((float *)childCol->stmtData.data)[k] = floatTmp;
5,628✔
1260
                    } else {
1261
                        ((float *)field->stmtData.data)[k] = floatTmp;
453,119✔
1262
                    }
1263
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
458,747✔
1264
                                        "%f,", floatTmp);
1265
                    break;
458,747✔
1266
                }
1267
                case TSDB_DATA_TYPE_DOUBLE: {
950,314✔
1268
                    double doubleTmp = tmpDoubleImpl(field, angle, index);
950,314✔
1269
                    if (childCol) {
950,318!
1270
                        ((double *)childCol->stmtData.data)[k] = doubleTmp;
×
1271
                    } else {
1272
                        ((double *)field->stmtData.data)[k] = doubleTmp;
950,318✔
1273
                    }
1274
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
950,318✔
1275
                                        "%f,", doubleTmp);
1276
                    break;
950,318✔
1277
                }
1278
                case TSDB_DATA_TYPE_BINARY:
997,585✔
1279
                case TSDB_DATA_TYPE_VARBINARY:
1280
                case TSDB_DATA_TYPE_NCHAR: {
1281
                    char *tmp = benchCalloc(1, field->length + 1, false);
997,585✔
1282
                    if (0 != tmpStr(tmp, stbInfo->iface, field, k)) {
997,615!
1283
                        free(tmp);
×
1284
                        return -1;
×
1285
                    }
1286
                    if (childCol) {
997,617!
1287
                        snprintf((char *)childCol->stmtData.data
×
1288
                                    + k * field->length,
×
1289
                                 field->length,
×
1290
                                "%s", tmp);
1291
                    } else {
1292
                        snprintf((char *)field->stmtData.data
997,617✔
1293
                                    + k * field->length,
997,617✔
1294
                                 field->length,
997,617✔
1295
                                "%s", tmp);
1296
                    }
1297
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
997,617✔
1298
                                        "'%s',", tmp);
1299
                    tmfree(tmp);
997,617✔
1300
                    break;
997,617✔
1301
                }
1302
                case TSDB_DATA_TYPE_GEOMETRY: {
20,200✔
1303
                    char *tmp = benchCalloc(1, field->length + 1, false);
20,200✔
1304
                    if (0 != tmpGeometry(tmp, stbInfo->iface, field, k)) {
20,200!
1305
                        tmfree(tmp);
×
1306
                        return -1;
×
1307
                    }
1308
                    if (childCol) {
20,200!
1309
                        snprintf((char *)childCol->stmtData.data
×
1310
                                    + k * field->length,
×
1311
                                 field->length,
×
1312
                                "%s", tmp);
1313
                    } else {
1314
                        snprintf((char *)field->stmtData.data
20,200✔
1315
                                    + k * field->length,
20,200✔
1316
                                 field->length,
20,200✔
1317
                                "%s", tmp);
1318
                    }
1319
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
20,200✔
1320
                                        "'%s',", tmp);
1321
                    tmfree(tmp);
20,200✔
1322
                    break;
20,200✔
1323
                }
1324
                case TSDB_DATA_TYPE_JSON: {
×
1325
                    n = tmpJson(sampleDataBuf, bufLen, pos, fieldsSize, field);
×
1326
                    if (n == -1) {
×
1327
                        return -1;
×
1328
                    }
1329
                    pos += n;
×
1330
                    goto skip_stmt;
×
1331
                }
1332
            }
1333
            if (TSDB_DATA_TYPE_JSON != field->type) {
10,462,613✔
1334
                if (n < 0 || n >= bufLen - pos) {
10,462,553!
1335
                    errorPrint("%s() LN%d snprintf overflow\n",
×
1336
                               __func__, __LINE__);
1337
                    return -1;
×
1338
                } else {
1339
                    pos += n;
10,462,571✔
1340
                }
1341
            }
1342
        }
1343
        debugPrint(" k=%" PRId64 " pos=%" PRId64 " line=%s\n", k, pos, line);
505,719!
1344

1345
skip_stmt:
505,719✔
1346
        if (pos > 0)
505,572!
1347
            *(sampleDataBuf + pos - 1) = 0;
505,576✔
1348
        angle += stbInfo->timestamp_step/stbInfo->angle_step;
505,572✔
1349
        if (angle > 360) {
505,572✔
1350
            angle -= 360;
145,087✔
1351
        }
1352

1353
    }
1354
    return 0;
679✔
1355
}
1356

1357
static int generateRandDataStmtForChildTable(
6✔
1358
    SSuperTable *stbInfo,
1359
    char *sampleDataBuf,
1360
    int64_t bufLen,
1361
    int lenOfOneRow, BArray *fields,
1362
    int64_t loop, BArray *childCols, int64_t loopBegin) {
1363
    //  generateRandDataStmtForChildTable()
1364
    for (int i = 0; i < fields->size; ++i) {
24✔
1365
        Field *field = benchArrayGet(fields, i);
18✔
1366
        ChildField *childField = benchArrayGet(childCols, i);
18✔
1367
        if (field->type == TSDB_DATA_TYPE_BINARY
18!
1368
                || field->type == TSDB_DATA_TYPE_NCHAR) {
18!
1369
            childField->stmtData.data = benchCalloc(
×
1370
                        1, loop * (field->length + 1), true);
×
1371
        } else {
1372
            childField->stmtData.data = benchCalloc(
18✔
1373
                    1, loop * field->length, true);
18✔
1374
        }
1375

1376
        // is_null
1377
        childField->stmtData.is_null = benchCalloc(sizeof(char), loop, true);
18✔
1378
        // lengths
1379
        childField->stmtData.lengths = benchCalloc(sizeof(int32_t), loop, true);
18✔
1380

1381
        // log
1382
        debugPrint("i=%d generateRandDataStmtForChildTable fields=%p %s malloc stmtData.data=%p\n", i, fields, field->name ,field->stmtData.data);
18!
1383

1384
    }
1385
    return fillStmt(
6✔
1386
        stbInfo,
1387
        sampleDataBuf,
1388
        bufLen,
1389
        lenOfOneRow, fields,
1390
        loop, false, childCols, loopBegin);
1391
}
1392

1393
static int generateRandDataStmt(
665✔
1394
    SSuperTable *stbInfo,
1395
    char *sampleDataBuf,
1396
    int64_t bufLen,
1397
    int lenOfOneRow, BArray *fields,
1398
    int64_t loop, bool tag, int64_t loopBegin) {
1399
    // generateRandDataStmt()
1400
    for (int i = 0; i < fields->size; ++i) {
3,126✔
1401
        Field *field = benchArrayGet(fields, i);
2,461✔
1402
        if (field->stmtData.data == NULL) {
2,461✔
1403
            // data
1404
            if (field->type == TSDB_DATA_TYPE_BINARY
1,062✔
1405
                    || field->type == TSDB_DATA_TYPE_NCHAR) {
972✔
1406
                field->stmtData.data = benchCalloc(1, loop * (field->length + 1), true);
100✔
1407
            } else {
1408
                field->stmtData.data = benchCalloc(1, loop * field->length, true);
962✔
1409
            }
1410

1411
            // is_null
1412
            field->stmtData.is_null = benchCalloc(sizeof(char), loop, true);
1,062✔
1413
            // lengths
1414
            field->stmtData.lengths = benchCalloc(sizeof(int32_t), loop, true);
1,062✔
1415

1416
            // log
1417
            debugPrint("i=%d generateRandDataStmt tag=%d fields=%p %s malloc stmtData.data=%p\n", i, tag, fields, field->name ,field->stmtData.data);
1,062!
1418
        }
1419
    }
1420

1421
    return fillStmt(
665✔
1422
        stbInfo,
1423
        sampleDataBuf,
1424
        bufLen,
1425
        lenOfOneRow, fields,
1426
        loop, tag, NULL, loopBegin);
1427
}
1428

1429
static int generateRandDataSmlTelnet(SSuperTable *stbInfo, char *sampleDataBuf,
168✔
1430
                     int bufLen,
1431
                      int lenOfOneRow, BArray * fields, int64_t loop,
1432
                      bool tag, int64_t loopBegin) {
1433
    int64_t index = loopBegin;
168✔
1434
    int angle = stbInfo->startTimestamp % 360; // 0 ~ 360
168✔
1435
    for (int64_t k = 0; k < loop; ++k, ++index) {
40,505✔
1436
        int64_t pos = k * lenOfOneRow;
40,337✔
1437
        int fieldsSize = fields->size;
40,337✔
1438
        if (!tag) {
40,337✔
1439
            fieldsSize = 1;
40,190✔
1440
        }
1441
        for (int i = 0; i < fieldsSize; ++i) {
82,399✔
1442
            Field * field = benchArrayGet(fields, i);
42,062✔
1443
            int n = 0;
42,062✔
1444
            switch (field->type) {
42,062!
1445
                case TSDB_DATA_TYPE_BOOL: {
155✔
1446
                    bool boolTmp = tmpBool(field);
155✔
1447
                    if (tag) {
155✔
1448
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1449
                                     "%s=%s ", field->name,
145✔
1450
                                        boolTmp ? "true" : "false");
1451
                    } else {
1452
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
10✔
1453
                                        "%s ", boolTmp ? "true" : "false");
1454
                    }
1455
                    break;
155✔
1456
                }
1457
                case TSDB_DATA_TYPE_TINYINT: {
155✔
1458
                    int8_t tinyint = tmpInt8Impl(field, index);
155✔
1459
                    if (tag) {
155✔
1460
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1461
                                        "%s=%di8 ", field->name, tinyint);
145✔
1462
                    } else {
1463
                        n = snprintf(sampleDataBuf + pos,
10✔
1464
                                     bufLen - pos, "%di8 ", tinyint);
10✔
1465
                    }
1466
                    break;
155✔
1467
                }
1468
                case TSDB_DATA_TYPE_UTINYINT: {
155✔
1469
                    uint8_t utinyint = tmpUint8Impl(field, index);
155✔
1470
                    if (tag) {
155✔
1471
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1472
                                        "%s=%uu8 ", field->name, utinyint);
145✔
1473
                    } else {
1474
                        n = snprintf(sampleDataBuf + pos,
10✔
1475
                                        bufLen - pos, "%uu8 ", utinyint);
10✔
1476
                    }
1477
                    break;
155✔
1478
                }
1479
                case TSDB_DATA_TYPE_SMALLINT: {
155✔
1480
                    int16_t smallint = tmpInt16Impl(field, index);
155✔
1481
                    if (tag) {
155✔
1482
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1483
                                        "%s=%di16 ", field->name, smallint);
145✔
1484
                    } else {
1485
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
10✔
1486
                                        "%di16 ", smallint);
1487
                    }
1488
                    break;
155✔
1489
                }
1490
                case TSDB_DATA_TYPE_USMALLINT: {
155✔
1491
                    uint16_t usmallint = tmpUint16Impl(field, index);
155✔
1492
                    if (tag) {
155✔
1493
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1494
                                        "%s=%uu16 ", field->name, usmallint);
145✔
1495
                    } else {
1496
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
10✔
1497
                                        "%uu16 ", usmallint);
1498
                    }
1499
                    break;
155✔
1500
                }
1501
                case TSDB_DATA_TYPE_INT: {
217✔
1502
                    int32_t intTmp = tmpInt32Impl(field, i, angle, index);
217✔
1503
                    if (tag) {
217✔
1504
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
147✔
1505
                                        "%s=%di32 ",
1506
                                        field->name, intTmp);
147✔
1507
                    } else {
1508
                        n = snprintf(sampleDataBuf + pos,
70✔
1509
                                        bufLen - pos,
70✔
1510
                                        "%di32 ", intTmp);
1511
                    }
1512
                    break;
217✔
1513
                }
1514
                case TSDB_DATA_TYPE_BIGINT: {
155✔
1515
                    int64_t bigintTmp = tmpInt64Impl(field, angle, index);
155✔
1516
                    if (tag) {
155✔
1517
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1518
                                     "%s=%"PRId64"i64 ",
1519
                                     field->name, bigintTmp);
145✔
1520
                    } else {
1521
                        n = snprintf(sampleDataBuf + pos,
10✔
1522
                                     bufLen - pos, "%"PRId64"i64 ", bigintTmp);
10✔
1523
                    }
1524
                    break;
155✔
1525
                }
1526
                case TSDB_DATA_TYPE_UINT: {
155✔
1527
                    uint32_t uintTmp = tmpUint32Impl(field, i, angle, index);
155✔
1528
                    if (tag) {
155✔
1529
                        n = snprintf(sampleDataBuf + pos,
145✔
1530
                                        bufLen - pos,
145✔
1531
                                        "%s=%uu32 ",
1532
                                        field->name, uintTmp);
145✔
1533
                    } else {
1534
                        n = snprintf(sampleDataBuf + pos,
10✔
1535
                                        bufLen - pos,
10✔
1536
                                        "%uu32 ", uintTmp);
1537
                    }
1538
                    break;
155✔
1539
                }
1540
                case TSDB_DATA_TYPE_UBIGINT:
155✔
1541
                case TSDB_DATA_TYPE_TIMESTAMP: {
1542
                    uint64_t ubigintTmp = tmpUint64Impl(field, angle, index);
155✔
1543
                    if (tag) {
155✔
1544
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1545
                                     "%s=%"PRIu64"u64 ",
1546
                                     field->name, ubigintTmp);
145✔
1547
                    } else {
1548
                        n = snprintf(sampleDataBuf + pos,
10✔
1549
                                     bufLen - pos, "%"PRIu64"u64 ", ubigintTmp);
10✔
1550
                    }
1551
                    break;
155✔
1552
                }
1553
                case TSDB_DATA_TYPE_FLOAT: {
40,155✔
1554
                    float floatTmp = tmpFloatImpl(field, i, angle, index);
40,155✔
1555
                    if (tag) {
40,155✔
1556
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1557
                                        "%s=%ff32 ", field->name, floatTmp);
145✔
1558
                    } else {
1559
                        n = snprintf(sampleDataBuf + pos,
40,010✔
1560
                                     bufLen - pos, "%ff32 ", floatTmp);
40,010✔
1561
                    }
1562
                    break;
40,155✔
1563
                }
1564
                case TSDB_DATA_TYPE_DOUBLE: {
155✔
1565
                    double double_ = tmpDoubleImpl(field, angle, index);
155✔
1566
                    if (tag) {
155✔
1567
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
145✔
1568
                                        "%s=%ff64 ", field->name, double_);
145✔
1569
                    } else {
1570
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
10✔
1571
                                     "%ff64 ", double_);
1572
                    }
1573
                    break;
155✔
1574
                }
1575
                case TSDB_DATA_TYPE_BINARY:
310✔
1576
                case TSDB_DATA_TYPE_VARBINARY:
1577
                case TSDB_DATA_TYPE_NCHAR: {
1578
                    char *tmp = benchCalloc(1, field->length + 1, false);
310✔
1579
                    if (0 != tmpStr(tmp, stbInfo->iface, field, index)) {
310!
1580
                        tmfree(tmp);
×
1581
                        return -1;
×
1582
                    }
1583
                    if (field->type == TSDB_DATA_TYPE_BINARY || field->type == TSDB_DATA_TYPE_VARBINARY) {
310!
1584
                        if (tag) {
156✔
1585
                            n = snprintf(sampleDataBuf + pos, bufLen - pos,
146✔
1586
                                            "%s=L\"%s\" ",
1587
                                           field->name, tmp);
146✔
1588
                        } else {
1589
                            n = snprintf(sampleDataBuf + pos, bufLen - pos,
10✔
1590
                                            "\"%s\" ", tmp);
1591
                        }
1592
                        if (n < 0 || n >= bufLen - pos) {
156!
1593
                            errorPrint("%s() LN%d snprintf overflow\n",
×
1594
                                       __func__, __LINE__);
1595
                            tmfree(tmp);
×
1596
                            return -1;
×
1597
                        } else {
1598
                            pos += n;
156✔
1599
                        }
1600
                    } else if (field->type == TSDB_DATA_TYPE_NCHAR) {
154!
1601
                        if (tag) {
154✔
1602
                            n = snprintf(sampleDataBuf + pos, bufLen - pos,
144✔
1603
                                            "%s=L\"%s\" ",
1604
                                           field->name, tmp);
144✔
1605
                        } else {
1606
                            n = snprintf(sampleDataBuf + pos, bufLen - pos,
10✔
1607
                                         "L\"%s\" ", tmp);
1608
                        }
1609
                        if (n < 0 || n >= bufLen - pos) {
154!
1610
                            errorPrint("%s() LN%d snprintf overflow\n",
×
1611
                                       __func__, __LINE__);
1612
                            tmfree(tmp);
×
1613
                            return -1;
×
1614
                        } else {
1615
                            pos += n;
154✔
1616
                        }
1617
                    }
1618
                    tmfree(tmp);
310✔
1619
                    break;
310✔
1620
                }
1621
                case TSDB_DATA_TYPE_GEOMETRY: {
×
1622
                    char *tmp = benchCalloc(1, field->length + 1, false);
×
1623
                    if (0 != tmpGeometry(tmp, stbInfo->iface, field, index)) {
×
1624
                        tmfree(tmp);
×
1625
                        return -1;
×
1626
                    }
1627
                    if (tag) {
×
1628
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
×
1629
                                        "%s=L\"%s\" ",
1630
                                        field->name, tmp);
×
1631
                    } else {
1632
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
×
1633
                                        "\"%s\" ", tmp);
1634
                    }
1635
                    if (n < 0 || n >= bufLen - pos) {
×
1636
                        errorPrint("%s() LN%d snprintf overflow\n",
×
1637
                                    __func__, __LINE__);
1638
                        tmfree(tmp);
×
1639
                        return -1;
×
1640
                    } else {
1641
                        pos += n;
×
1642
                    }
1643
                    tmfree(tmp);
×
1644
                    break;
×
1645
                }
UNCOV
1646
                case TSDB_DATA_TYPE_JSON: {
×
UNCOV
1647
                    n = tmpJson(sampleDataBuf, bufLen, pos, fieldsSize, field);
×
1648
                    if (n == -1) {
×
1649
                        return -1;
×
1650
                    }
1651
                    pos += n;
×
1652
                    goto skip_telnet;
×
1653
                }
1654
            }
1655
            if (TSDB_DATA_TYPE_JSON != field->type) {
42,062✔
1656
                if (n < 0 || n >= bufLen - pos) {
42,061!
1657
                    errorPrint("%s() LN%d snprintf overflow\n",
×
1658
                               __func__, __LINE__);
1659
                    return -1;
×
1660
                } else {
1661
                    pos += n;
42,061✔
1662
                }
1663
            }
1664
        }
1665
skip_telnet:
40,337✔
1666
        *(sampleDataBuf + pos - 1) = 0;
40,337✔
1667
        angle += stbInfo->timestamp_step/stbInfo->angle_step;
40,337✔
1668
        if (angle > 360) {
40,337✔
1669
            angle -= 360;
131✔
1670
        }
1671

1672
    }
1673

1674
    return 0;
168✔
1675
}
1676

1677
static int generateRandDataSmlJson(SSuperTable *stbInfo, char *sampleDataBuf,
36✔
1678
                     int bufLen,
1679
                      int lenOfOneRow, BArray * fields, int64_t loop,
1680
                      bool tag, int64_t loopBegin) {
1681
    int64_t index = loopBegin;
36✔
1682
    int angle = stbInfo->startTimestamp % 360; // 0 ~ 360
36✔
1683
    for (int64_t k = 0; k < loop; ++k, ++index) {
80,356✔
1684
        int64_t pos = k * lenOfOneRow;
80,320✔
1685
        int fieldsSize = fields->size;
80,320✔
1686
        for (int i = 0; i < fieldsSize; ++i) {
320,640✔
1687
            Field * field = benchArrayGet(fields, i);
240,320✔
1688
            int n = 0;
240,320✔
1689
            switch (field->type) {
240,320!
1690
                case TSDB_DATA_TYPE_BOOL: {
30✔
1691
                    bool boolTmp = tmpBool(field);
30✔
1692
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
30✔
1693
                                    "%s,", boolTmp ? "true" : "false");
1694
                    break;
30✔
1695
                }
1696
                case TSDB_DATA_TYPE_TINYINT: {
30✔
1697
                    int8_t tinyint = tmpInt8Impl(field, index);
30✔
1698
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
30✔
1699
                                        "%d,", tinyint);
1700
                    break;
30✔
1701
                }
1702
                case TSDB_DATA_TYPE_UTINYINT: {
×
1703
                    uint8_t utinyint = tmpUint8Impl(field, index);
×
1704
                    n = snprintf(sampleDataBuf + pos,
×
1705
                                        bufLen - pos, "%u,", utinyint);
×
1706
                    break;
×
1707
                }
1708
                case TSDB_DATA_TYPE_SMALLINT: {
30✔
1709
                    int16_t smallint = tmpInt16Impl(field, index);
30✔
1710
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
30✔
1711
                                        "%d,", smallint);
1712
                    break;
30✔
1713
                }
1714
                case TSDB_DATA_TYPE_USMALLINT: {
×
1715
                    uint16_t usmallint = tmpUint16Impl(field, index);
×
1716
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
×
1717
                                        "%u,", usmallint);
1718
                    break;
×
1719
                }
1720
                case TSDB_DATA_TYPE_INT: {
80,070✔
1721
                    int32_t intTmp = tmpInt32Impl(field, i, angle, index);
80,070✔
1722
                    n = snprintf(sampleDataBuf + pos,
80,070✔
1723
                                 bufLen - pos, "%d,", intTmp);
80,070✔
1724
                    break;
80,070✔
1725
                }
1726
                case TSDB_DATA_TYPE_BIGINT: {
30✔
1727
                    int64_t bigintTmp = tmpInt64Impl(field, angle, index);
30✔
1728
                    n = snprintf(sampleDataBuf + pos,
30✔
1729
                                 bufLen - pos, "%"PRId64",", bigintTmp);
30✔
1730
                    break;
30✔
1731
                }
1732
                case TSDB_DATA_TYPE_UINT: {
×
1733
                    uint32_t uintTmp = tmpUint32Impl(field, i, angle, index);
×
1734
                    n = snprintf(sampleDataBuf + pos,
×
1735
                                 bufLen - pos, "%u,", uintTmp);
×
1736
                    break;
×
1737
                }
1738
                case TSDB_DATA_TYPE_UBIGINT:
×
1739
                case TSDB_DATA_TYPE_TIMESTAMP: {
1740
                    uint64_t ubigintTmp = tmpUint64Impl(field, angle, index);
×
1741
                    n = snprintf(sampleDataBuf + pos,
×
1742
                                 bufLen - pos, "%"PRIu64",", ubigintTmp);
×
1743
                    break;
×
1744
                }
1745
                case TSDB_DATA_TYPE_FLOAT: {
160,030✔
1746
                    float floatTmp = tmpFloatImpl(field, i, angle, index);
160,030✔
1747
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
160,030✔
1748
                                        "%f,", floatTmp);
1749
                    break;
160,030✔
1750
                }
1751
                case TSDB_DATA_TYPE_DOUBLE: {
30✔
1752
                    double double_ = tmpDoubleImpl(field, angle, index);
30✔
1753
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
30✔
1754
                                        "%f,", double_);
1755
                    break;
30✔
1756
                }
1757
                case TSDB_DATA_TYPE_BINARY:
70✔
1758
                case TSDB_DATA_TYPE_VARBINARY:
1759
                case TSDB_DATA_TYPE_NCHAR: {
1760
                    char *tmp = benchCalloc(1, field->length + 1, false);
70✔
1761
                    if (0 != tmpStr(tmp, stbInfo->iface, field, k)) {
70!
1762
                        free(tmp);
×
1763
                        return -1;
×
1764
                    }
1765
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
70✔
1766
                                        "'%s',", tmp);
1767
                    tmfree(tmp);
70✔
1768
                    break;
70✔
1769
                }
1770
                case TSDB_DATA_TYPE_JSON: {
×
1771
                    n = tmpJson(sampleDataBuf, bufLen, pos, fieldsSize, field);
×
1772
                    if (n == -1) {
×
1773
                        return -1;
×
1774
                    }
1775
                    pos += n;
×
1776
                    goto skip_json;
×
1777
                }
1778
            }
1779
            if (TSDB_DATA_TYPE_JSON != field->type) {
240,320!
1780
                if (n < 0 || n >= bufLen - pos) {
240,320!
1781
                    errorPrint("%s() LN%d snprintf overflow\n",
×
1782
                               __func__, __LINE__);
1783
                    return -1;
×
1784
                } else {
1785
                    pos += n;
240,320✔
1786
                }
1787
            }
1788
        }
1789
skip_json:
80,320✔
1790
        *(sampleDataBuf + pos - 1) = 0;
80,320✔
1791
        angle += stbInfo->timestamp_step/stbInfo->angle_step;
80,320✔
1792
        if (angle > 360) {
80,320✔
1793
            angle -= 360;
225✔
1794
        }
1795
    }
1796

1797
    return 0;
36✔
1798
}
1799

1800
static int generateRandDataSmlLine(SSuperTable *stbInfo, char *sampleDataBuf,
66✔
1801
                     int bufLen,
1802
                      int lenOfOneRow, BArray * fields, int64_t loop,
1803
                      bool tag, int64_t loopBegin) {
1804
    int64_t index = loopBegin;
66✔
1805
    int angle = stbInfo->startTimestamp % 360; // 0 ~ 360                    
66✔
1806
    for (int64_t k = 0; k < loop; ++k, ++index) {
140,351✔
1807
        int64_t pos = k * lenOfOneRow;
140,284✔
1808
        int n = 0;
140,284✔
1809
        if (tag) {
140,284✔
1810
            n = snprintf(sampleDataBuf + pos,
54✔
1811
                           bufLen - pos,
54✔
1812
                           "%s,", stbInfo->stbName);
1813
            if (n < 0 || n >= bufLen - pos) {
54!
1814
                errorPrint("%s() LN%d snprintf overflow\n",
×
1815
                           __func__, __LINE__);
1816
                return -1;
×
1817
            } else {
1818
                pos += n;
54✔
1819
            }
1820
        }
1821

1822
        int fieldsSize = fields->size;
140,284✔
1823
        for (int i = 0; i < fieldsSize; ++i) {
563,820✔
1824
            Field * field = benchArrayGet(fields, i);
423,535✔
1825
            switch (field->type) {
423,535!
1826
                case TSDB_DATA_TYPE_BOOL: {
270✔
1827
                    bool boolTmp = tmpBool(field);
270✔
1828
                    n = snprintf(sampleDataBuf + pos, bufLen - pos, "%s=%s,",
270✔
1829
                                 field->name, boolTmp ? "true" : "false");
270✔
1830
                    break;
270✔
1831
                }
1832
                case TSDB_DATA_TYPE_TINYINT: {
270✔
1833
                    int8_t tinyint = tmpInt8Impl(field, index);
270✔
1834
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1835
                                    "%s=%di8,", field->name, tinyint);
270✔
1836
                    break;
270✔
1837
                }
1838
                case TSDB_DATA_TYPE_UTINYINT: {
270✔
1839
                    uint8_t utinyint = tmpUint8Impl(field, index);
270✔
1840
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1841
                                    "%s=%uu8,", field->name, utinyint);
270✔
1842
                    break;
270✔
1843
                }
1844
                case TSDB_DATA_TYPE_SMALLINT: {
270✔
1845
                    int16_t smallint = tmpInt16Impl(field, index);
270✔
1846
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1847
                                    "%s=%di16,", field->name, smallint);
270✔
1848
                    break;
270✔
1849
                }
1850
                case TSDB_DATA_TYPE_USMALLINT: {
270✔
1851
                    uint16_t usmallint = tmpUint16Impl(field, index);
270✔
1852
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1853
                                    "%s=%uu16,",
1854
                                    field->name, usmallint);
270✔
1855
                    break;
270✔
1856
                }
1857
                case TSDB_DATA_TYPE_INT: {
140,284✔
1858
                    int32_t intTmp;
1859
                    if (tag) {
140,284✔
1860
                        intTmp = tmpInt32ImplTag(field, i, index);
54✔
1861
                    } else {
1862
                        intTmp = tmpInt32Impl(field, i, angle, index);
140,230✔
1863
                    }                    
1864
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
140,284✔
1865
                                    "%s=%di32,",
1866
                                    field->name, intTmp);
140,284✔
1867
                    break;
140,284✔
1868
                }
1869
                case TSDB_DATA_TYPE_BIGINT: {
270✔
1870
                    int64_t bigintTmp = tmpInt64Impl(field, angle, index);
270✔
1871
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1872
                                 "%s=%"PRId64"i64,", field->name, bigintTmp);
270✔
1873
                    break;
270✔
1874
                }
1875
                case TSDB_DATA_TYPE_UINT: {
270✔
1876
                    uint32_t uintTmp = tmpUint32Impl(field, i, angle, index);
270✔
1877
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1878
                                    "%s=%uu32,", field->name, uintTmp);
270✔
1879
                    break;
270✔
1880
                }
1881
                case TSDB_DATA_TYPE_UBIGINT:
270✔
1882
                case TSDB_DATA_TYPE_TIMESTAMP: {
1883
                    uint64_t ubigintTmp = tmpUint64Impl(field, angle, index);
270✔
1884
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1885
                                 "%s=%"PRIu64"u64,", field->name, ubigintTmp);
270✔
1886
                    break;
270✔
1887
                }
1888
                case TSDB_DATA_TYPE_FLOAT: {
280,270✔
1889
                    float floatTmp = tmpFloatImpl(field, i, angle, index);
280,270✔
1890
                    n = snprintf(sampleDataBuf + pos,
280,270✔
1891
                                    bufLen - pos, "%s=%ff32,",
280,270✔
1892
                                    field->name, floatTmp);
280,270✔
1893
                    break;
280,270✔
1894
                }
1895
                case TSDB_DATA_TYPE_DOUBLE: {
270✔
1896
                    double doubleTmp = tmpDoubleImpl(field, angle, index);
270✔
1897
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1898
                                 "%s=%ff64,", field->name, doubleTmp);
270✔
1899
                    break;
270✔
1900
                }
1901
                case TSDB_DATA_TYPE_BINARY:
554✔
1902
                case TSDB_DATA_TYPE_VARBINARY:
1903
                case TSDB_DATA_TYPE_NCHAR: {
1904
                    char *tmp = benchCalloc(1, field->length + 1, false);
554✔
1905
                    if (0 != tmpStr(tmp, stbInfo->iface, field, k)) {
554!
1906
                        free(tmp);
×
1907
                        return -1;
×
1908
                    }
1909
                    if (field->type == TSDB_DATA_TYPE_BINARY) {
554✔
1910
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
284✔
1911
                                        "%s=\"%s\",",
1912
                                       field->name, tmp);
284✔
1913
                    } else if (field->type == TSDB_DATA_TYPE_NCHAR) {
270!
1914
                        n = snprintf(sampleDataBuf + pos, bufLen - pos,
270✔
1915
                                        "%s=L\"%s\",",
1916
                                       field->name, tmp);
270✔
1917
                    }
1918
                    tmfree(tmp);
554✔
1919
                    break;
554✔
1920
                }
1921
                case TSDB_DATA_TYPE_GEOMETRY: {
×
1922
                    char *tmp = benchCalloc(1, field->length + 1, false);
×
1923
                    if (0 != tmpGeometry(tmp, stbInfo->iface, field, index)) {
×
1924
                        tmfree(tmp);
×
1925
                        return -1;
×
1926
                    }
1927
                    n = snprintf(sampleDataBuf + pos, bufLen - pos,
×
1928
                                    "%s=\"%s\",",
1929
                                    field->name, tmp);
×
1930
                    tmfree(tmp);
×
1931
                    break;
×
1932
                }
1933
                case TSDB_DATA_TYPE_JSON: {
×
1934
                    n = tmpJson(sampleDataBuf, bufLen, pos,
×
1935
                                   fieldsSize, field);
1936
                    if (n < 0 || n >= bufLen) {
×
1937
                        errorPrint("%s() LN%d snprintf overflow\n",
×
1938
                                   __func__, __LINE__);
1939
                        return -1;
×
1940
                    } else {
1941
                        pos += n;
×
1942
                    }
1943
                    goto skip_line;
×
1944
                }
1945
            }
1946
            if (TSDB_DATA_TYPE_JSON != field->type) {
423,536!
1947
                if (n < 0 || n >= bufLen - pos) {
423,536!
1948
                    errorPrint("%s() LN%d snprintf overflow\n",
×
1949
                               __func__, __LINE__);
1950
                    return -1;
×
1951
                } else {
1952
                    pos += n;
423,536✔
1953
                }
1954
            }
1955
        }
1956
skip_line:
140,285✔
1957
        *(sampleDataBuf + pos - 1) = 0;
140,285✔
1958
        angle += stbInfo->timestamp_step/stbInfo->angle_step;
140,285✔
1959
        if (angle > 360) {
140,285✔
1960
            angle -= 360;
392✔
1961
        }
1962

1963
    }
1964

1965
    return 0;
67✔
1966
}
1967

1968
static int generateRandDataSml(SSuperTable *stbInfo, char *sampleDataBuf,
270✔
1969
                     int64_t bufLen,
1970
                      int lenOfOneRow, BArray * fields, int64_t loop,
1971
                      bool tag, int64_t loopBegin) {
1972
    int     protocol = stbInfo->lineProtocol;
270✔
1973

1974
    switch (protocol) {
270✔
1975
        case TSDB_SML_LINE_PROTOCOL:
66✔
1976
            return generateRandDataSmlLine(stbInfo, sampleDataBuf,
66✔
1977
                                    bufLen, lenOfOneRow, fields, loop, tag, loopBegin);
1978
        case TSDB_SML_TELNET_PROTOCOL:
168✔
1979
            return generateRandDataSmlTelnet(stbInfo, sampleDataBuf,
168✔
1980
                                    bufLen, lenOfOneRow, fields, loop, tag, loopBegin);
1981
        default:
36✔
1982
            return generateRandDataSmlJson(stbInfo, sampleDataBuf,
36✔
1983
                                    bufLen, lenOfOneRow, fields, loop, tag, loopBegin);
1984
    }
1985

1986
    return -1;
1987
}
1988

1989
int generateRandData(SSuperTable *stbInfo, char *sampleDataBuf,
2,624✔
1990
                     int64_t bufLen,
1991
                     int lenOfOneRow, BArray *fields,
1992
                     int64_t loop,
1993
                     bool tag, BArray *childCols, int64_t loopBegin) {
1994
    int     iface = stbInfo->iface;
2,624✔
1995
    switch (iface) {
2,624!
1996
        case TAOSC_IFACE:
1,674✔
1997
            return generateRandDataSQL(stbInfo, sampleDataBuf,
1,674✔
1998
                                    bufLen, lenOfOneRow, fields, loop, tag, loopBegin);
1999
        // REST
2000
        case REST_IFACE:
9✔
2001
            return generateRandDataSQL(stbInfo, sampleDataBuf,
9✔
2002
                                    bufLen, lenOfOneRow, fields, loop, tag, loopBegin);
2003
        case STMT_IFACE:
671✔
2004
        case STMT2_IFACE:
2005
            if (childCols) {
671✔
2006
                return generateRandDataStmtForChildTable(stbInfo,
6✔
2007
                                                         sampleDataBuf,
2008
                                    bufLen, lenOfOneRow, fields, loop,
2009
                                                         childCols, loopBegin);
2010
            } else {
2011
                return generateRandDataStmt(stbInfo, sampleDataBuf,
665✔
2012
                                    bufLen, lenOfOneRow, fields, loop, tag, loopBegin);
2013
            }
2014
        case SML_IFACE:
270✔
2015
        case SML_REST_IFACE: // REST
2016
            return generateRandDataSml(stbInfo, sampleDataBuf,
270✔
2017
                                    bufLen, lenOfOneRow, fields, loop, tag, loopBegin);
2018
        default:
×
2019
            errorPrint("Unknown iface: %d\n", iface);
×
2020
            break;
×
2021
    }
2022

2023
    return -1;
×
2024
}
2025

2026
static BArray *initChildCols(int colsSize) {
8✔
2027
    BArray *childCols = benchArrayInit(colsSize,
8✔
2028
                                       sizeof(ChildField));
2029
    for (int col = 0; col < colsSize; col++) {
28✔
2030
        ChildField *childCol = benchCalloc(
20✔
2031
                1, sizeof(ChildField), true);
2032
        benchArrayPush(childCols, childCol);
20✔
2033
    }
2034
    return childCols;
8✔
2035
}
2036

2037
int prepareSampleData(SDataBase* database, SSuperTable* stbInfo) {
357✔
2038
    stbInfo->lenOfCols = accumulateRowLen(stbInfo->cols, stbInfo->iface);
357✔
2039
    stbInfo->lenOfTags = accumulateRowLen(stbInfo->tags, stbInfo->iface);
357✔
2040
    if (stbInfo->partialColNum != 0
357✔
2041
            && ((stbInfo->iface == TAOSC_IFACE
10✔
2042
                || stbInfo->iface == REST_IFACE))) {
1!
2043
        // check valid
2044
        if(stbInfo->partialColFrom >= stbInfo->cols->size) {
9!
2045
            stbInfo->partialColFrom = 0;
×
2046
            infoPrint("stbInfo->partialColFrom(%d) is large than stbInfo->cols->size(%zd) \n ",stbInfo->partialColFrom,stbInfo->cols->size);
×
2047
        }
2048

2049
        if (stbInfo->partialColFrom + stbInfo->partialColNum > stbInfo->cols->size) {
9✔
2050
            stbInfo->partialColNum = stbInfo->cols->size - stbInfo->partialColFrom ;
4✔
2051
        }
2052

2053
        if(stbInfo->partialColNum < stbInfo->cols->size) {
9✔
2054
            stbInfo->partialColNameBuf =
5✔
2055
                    benchCalloc(1, TSDB_MAX_ALLOWED_SQL_LEN, true);
5✔
2056
            int pos = 0;
5✔
2057
            int n;
2058
            n = snprintf(stbInfo->partialColNameBuf + pos,
5✔
2059
                            TSDB_MAX_ALLOWED_SQL_LEN - pos,
5✔
2060
                            TS_COL_NAME);
2061
            if (n < 0 || n > TSDB_MAX_ALLOWED_SQL_LEN - pos) {
5!
2062
                errorPrint("%s() LN%d snprintf overflow\n",
×
2063
                           __func__, __LINE__);
2064
            } else {
2065
                pos += n;
5✔
2066
            }
2067
            for (int i = stbInfo->partialColFrom; i < stbInfo->partialColFrom + stbInfo->partialColNum; ++i) {
22✔
2068
                Field * col = benchArrayGet(stbInfo->cols, i);
17✔
2069
                n = snprintf(stbInfo->partialColNameBuf+pos,
17✔
2070
                                TSDB_MAX_ALLOWED_SQL_LEN - pos,
17✔
2071
                               ",%s", col->name);
17✔
2072
                if (n < 0 || n > TSDB_MAX_ALLOWED_SQL_LEN - pos) {
17!
2073
                    errorPrint("%s() LN%d snprintf overflow at %d\n",
×
2074
                               __func__, __LINE__, i);
2075
                } else {
2076
                    pos += n;
17✔
2077
                }
2078
            }
2079
            
2080
            // first part set noen
2081
            for (uint32_t i = 0; i < stbInfo->partialColFrom; ++i) {
5!
2082
                Field * col = benchArrayGet(stbInfo->cols, i);
×
2083
                col->none = true;
×
2084
            }
2085
            // last part set none
2086
            for (uint32_t i = stbInfo->partialColFrom + stbInfo->partialColNum; i < stbInfo->cols->size; ++i) {
45✔
2087
                Field * col = benchArrayGet(stbInfo->cols, i);
40✔
2088
                col->none = true;
40✔
2089
            }
2090
            debugPrint("partialColNameBuf: %s\n",
5!
2091
                       stbInfo->partialColNameBuf);
2092
        }
2093
    } else {
2094
        stbInfo->partialColNum = stbInfo->cols->size;
348✔
2095
    }
2096
    stbInfo->sampleDataBuf =
357✔
2097
            benchCalloc(
357✔
2098
                1, stbInfo->lenOfCols*g_arguments->prepared_rand, true);
357✔
2099
    infoPrint(
357✔
2100
              "generate stable<%s> columns data with lenOfCols<%u> * "
2101
              "prepared_rand<%" PRIu64 ">\n",
2102
              stbInfo->stbName, stbInfo->lenOfCols, g_arguments->prepared_rand);
2103
    if (stbInfo->random_data_source) {
357✔
2104
        if (g_arguments->mistMode) {
349✔
2105
            infoPrint("Each child table using different random prepare data pattern. need "
3✔
2106
            "all memory(%d M) = childs(%"PRId64") * prepared_rand(%"PRId64") * lenOfCols(%d) \n",
2107
            (int32_t)(stbInfo->childTblCount*g_arguments->prepared_rand*stbInfo->lenOfCols/1024/1024),
2108
            stbInfo->childTblCount, g_arguments->prepared_rand, stbInfo->lenOfCols);
2109
            for (int64_t child = 0; child < stbInfo->childTblCount; child++) {
11✔
2110
                SChildTable *childTbl = stbInfo->childTblArray[child];
8✔
2111
                if (STMT_IFACE == stbInfo->iface || STMT2_IFACE == stbInfo->iface) {
8✔
2112
                    childTbl->childCols = initChildCols(stbInfo->cols->size);
6✔
2113
                }
2114
                childTbl->sampleDataBuf =
8✔
2115
                    benchCalloc(
8✔
2116
                        1, stbInfo->lenOfCols*g_arguments->prepared_rand, true);
8✔
2117
                if (generateRandData(stbInfo, childTbl->sampleDataBuf,
8!
2118
                             stbInfo->lenOfCols*g_arguments->prepared_rand,
8✔
2119
                             stbInfo->lenOfCols,
8✔
2120
                             stbInfo->cols,
2121
                             g_arguments->prepared_rand,
8✔
2122
                             false, childTbl->childCols, 0)) {
2123
                    errorPrint("Failed to generate data for table %s\n",
×
2124
                               childTbl->name);
2125
                    return -1;
×
2126
                }
2127
                childTbl->useOwnSample = true;
8✔
2128
            }
2129
        } else {
2130
            if (generateRandData(stbInfo, stbInfo->sampleDataBuf,
346!
2131
                             stbInfo->lenOfCols*g_arguments->prepared_rand,
346✔
2132
                             stbInfo->lenOfCols,
346✔
2133
                             stbInfo->cols,
2134
                             g_arguments->prepared_rand,
346✔
2135
                             false, NULL, 0)) {
2136
                return -1;
×
2137
            }
2138
        }
2139
        debugPrint("sampleDataBuf: %s\n", stbInfo->sampleDataBuf);
349✔
2140
    } else {
2141
        if (stbInfo->useSampleTs) {
8✔
2142
            if (getAndSetRowsFromCsvFile(
6!
2143
                    stbInfo->sampleFile, &stbInfo->insertRows)) {
6✔
2144
                return -1;
×
2145
            }
2146
        }
2147
        if (generateSampleFromCsv(stbInfo->sampleDataBuf,
8!
2148
                                        stbInfo->sampleFile, NULL, stbInfo->lenOfCols,
8✔
2149
                                        g_arguments->prepared_rand)) {
8✔
2150
            errorPrint("Failed to generate sample from csv file %s\n",
×
2151
                    stbInfo->sampleFile);
2152
            return -1;
×
2153
        }
2154

2155
        debugPrint("sampleDataBuf: %s\n", stbInfo->sampleDataBuf);
8!
2156
        if (stbInfo->childTblSample) {
8✔
2157
            if (NULL == strstr(stbInfo->childTblSample, "XXXX")) {
2!
2158
                errorPrint("Child table sample file pattern has no %s\n",
×
2159
                   "XXXX");
2160
                return -1;
×
2161
            }
2162
            for (int64_t child = 0; child < stbInfo->childTblCount; child++) {
18✔
2163
                char sampleFilePath[MAX_PATH_LEN] = {0};
16✔
2164
                getSampleFileNameByPattern(sampleFilePath, stbInfo, child);
16✔
2165
                if (0 != access(sampleFilePath, F_OK)) {
16✔
2166
                    continue;
12✔
2167
                }
2168
                SChildTable *childTbl = stbInfo->childTblArray[child];
4✔
2169
                infoPrint("Found specified sample file for table %s\n",
4✔
2170
                          childTbl->name);
2171
                if (getAndSetRowsFromCsvFile(sampleFilePath,
4!
2172
                                             &(childTbl->insertRows))) {
2173
                    errorPrint("Failed to get sample data rows for table %s\n",
×
2174
                          childTbl->name);
2175
                    return -1;
×
2176
                }
2177

2178
                childTbl->sampleDataBuf =
4✔
2179
                    benchCalloc(
4✔
2180
                        1, stbInfo->lenOfCols*g_arguments->prepared_rand, true);
4✔
2181
                if (generateSampleFromCsv(
4!
2182
                            childTbl->sampleDataBuf,
2183
                            sampleFilePath,
2184
                            NULL,
2185
                            stbInfo->lenOfCols,
4✔
2186
                            g_arguments->prepared_rand)) {
4✔
2187
                    errorPrint("Failed to generate sample from file "
×
2188
                                   "for child table %"PRId64"\n",
2189
                                    child);
2190
                    return -1;
×
2191
                }
2192
                if (STMT_IFACE == stbInfo->iface || STMT2_IFACE == stbInfo->iface) {
4!
2193
                    childTbl->childCols = initChildCols(stbInfo->cols->size);
2✔
2194
                }
2195
                childTbl->useOwnSample = true;
4✔
2196
                debugPrint("sampleDataBuf: %s\n", childTbl->sampleDataBuf);
4!
2197
            }
2198
        }
2199
    }
2200

2201
    if (0 != convertServAddr(
357!
2202
            stbInfo->iface,
357✔
2203
            stbInfo->tcpTransfer,
357✔
2204
            stbInfo->lineProtocol)) {
357✔
2205
        return -1;
×
2206
    }    
2207
    return 0;
357✔
2208
}
2209

2210
int64_t getTSRandTail(int64_t timeStampStep, int32_t seq, int disorderRatio,
20✔
2211
                      int disorderRange) {
2212
    int64_t randTail = timeStampStep * seq;
20✔
2213
    if (disorderRatio > 0) {
20!
2214
        int rand_num = taosRandom() % 100;
20✔
2215
        if (rand_num < disorderRatio) {
20✔
2216
            randTail = (randTail + (taosRandom() % disorderRange + 1)) * (-1);
12✔
2217
        }
2218
    }
2219
    return randTail;
20✔
2220
}
2221

2222
uint32_t bindParamBatch(threadInfo *pThreadInfo,
87,786✔
2223
                        uint32_t batch, int64_t startTime, int64_t pos,
2224
                        SChildTable *childTbl, int32_t *pkCur, int32_t *pkCnt, int32_t *n, int64_t *delay2, int64_t *delay3) {
2225
    TAOS_STMT   *stmt = pThreadInfo->conn->stmt;
87,786✔
2226
    SSuperTable *stbInfo = pThreadInfo->stbInfo;
87,786✔
2227
    uint32_t     columnCount = stbInfo->cols->size;
87,786✔
2228

2229
    //if (!pThreadInfo->stmtBind || stbInfo->interlaceRows > 0 ) {
2230
    {
2231
        pThreadInfo->stmtBind = true;
87,786✔
2232
        memset(pThreadInfo->bindParams, 0,
87,786✔
2233
            (sizeof(TAOS_MULTI_BIND) * (columnCount + 1)));
87,786✔
2234

2235
        for (int c = 0; c <= columnCount; c++) {
398,245✔
2236
            TAOS_MULTI_BIND *param =
311,231✔
2237
                (TAOS_MULTI_BIND *)(pThreadInfo->bindParams +
311,231✔
2238
                                    sizeof(TAOS_MULTI_BIND) * c);
311,231✔
2239
            char data_type;
2240
            if (c == 0) {
311,231✔
2241
                data_type = TSDB_DATA_TYPE_TIMESTAMP;
87,873✔
2242
                param->buffer_length = sizeof(int64_t);
87,873✔
2243
                if (stbInfo->useSampleTs) {
87,873✔
2244
                    param->buffer = pThreadInfo->bind_ts_array + pos;
66✔
2245
                } else {
2246
                    param->buffer = pThreadInfo->bind_ts_array;
87,807✔
2247
                }
2248
            } else {
2249
                Field *col = benchArrayGet(stbInfo->cols, c - 1);
223,358✔
2250
                data_type = col->type;
223,279✔
2251
                if (childTbl->useOwnSample) {
223,279!
UNCOV
2252
                    ChildField *childCol = benchArrayGet(childTbl->childCols, c-1);
×
2253
                    param->buffer = (char *)childCol->stmtData.data + pos * col->length;
14✔
2254
                    param->is_null = childCol->stmtData.is_null + pos;
14✔
2255
                } else {
2256
                    param->buffer = (char *)col->stmtData.data + pos * col->length;
223,286✔
2257
                    param->is_null = col->stmtData.is_null + pos;
223,286✔
2258
                }
2259
                param->buffer_length = col->length;
223,300✔
2260
                debugPrint("col[%d]: type: %s, len: %d\n", c,
223,300!
2261
                        convertDatatypeToString(data_type),
2262
                        col->length);
2263
            }
2264
            param->buffer_type = data_type;
310,459✔
2265
            param->length = pThreadInfo->lengths[c];
310,459✔
2266

2267
            for (int b = 0; b < batch; b++) {
754,108,127✔
2268
                param->length[b] = (int32_t)param->buffer_length;
753,797,668✔
2269
            }
2270
            param->num = batch;
310,459✔
2271
        }
2272
    }
2273

2274
    if (!stbInfo->useSampleTs) {
87,014!
2275
        // set first column ts array values
2276
        for (uint32_t k = 0; k < batch; k++) {
218,334,862✔
2277
            /* columnCount + 1 (ts) */
2278
            if (stbInfo->disorderRatio) {
218,247,209✔
2279
                *(pThreadInfo->bind_ts_array + k) =
20✔
2280
                    startTime + getTSRandTail(stbInfo->timestamp_step, *n,
20✔
2281
                                            stbInfo->disorderRatio,
2282
                                            stbInfo->disorderRange);
2283
            } else {
2284
                *(pThreadInfo->bind_ts_array + k) = startTime + stbInfo->timestamp_step * (*n);
218,247,189✔
2285
            }
2286

2287
            // check n need add
2288
            if (!stbInfo->primary_key || needChangeTs(stbInfo, pkCur, pkCnt)) {
218,247,209!
2289
                *n = *n + 1;
218,274,887✔
2290
            }
2291
        }
2292
    }
2293

2294
    /*
2295
      1. The last batch size may be smaller than the previous batch size.
2296
      2. When inserting another table, the batch size reset again(bigger than lastBatchSize)
2297
    */        
2298
    int lastBatchSize = ((TAOS_MULTI_BIND *) pThreadInfo->bindParams)->num;
87,014✔
2299
    if (batch != lastBatchSize) {
87,014!
2300
        for (int c = 0; c < columnCount + 1; c++) {
×
2301
            TAOS_MULTI_BIND *param =
×
2302
                    (TAOS_MULTI_BIND *) (pThreadInfo->bindParams +
×
2303
                    sizeof(TAOS_MULTI_BIND) * c);
×
2304
            param->num = batch;
×
2305
        }
2306
    }
2307

2308
    int64_t start = toolsGetTimestampUs();
87,014✔
2309
    if (taos_stmt_bind_param_batch(
87,945!
2310
            stmt, (TAOS_MULTI_BIND *)pThreadInfo->bindParams)) {
87,848✔
2311
        errorPrint("taos_stmt_bind_param_batch() failed! reason: %s\n",
×
2312
                   taos_stmt_errstr(stmt));
2313
        return 0;
×
2314
    }
2315
    *delay2 += toolsGetTimestampUs() - start;
87,945✔
2316

2317
    if(stbInfo->autoTblCreating) {
87,945✔
2318
        start = toolsGetTimestampUs();
40,026✔
2319
        if (taos_stmt_add_batch(pThreadInfo->conn->stmt) != 0) {
40,022!
2320
            errorPrint("taos_stmt_add_batch() failed! reason: %s\n",
×
2321
                    taos_stmt_errstr(pThreadInfo->conn->stmt));
2322
            return 0;
×
2323
        }
2324
        if(delay3) {
40,004!
2325
            *delay3 += toolsGetTimestampUs() - start;
40,007✔
2326
        }
2327
    }
2328
    return batch;
87,937✔
2329
}
2330

2331
void generateSmlJsonTags(tools_cJSON *tagsList,
171✔
2332
                         char **sml_tags_json_array,
2333
                         SSuperTable *stbInfo,
2334
                            uint64_t start_table_from, int tbSeq) {
2335
    tools_cJSON * tags = tools_cJSON_CreateObject();
171✔
2336
    char *  tbName = benchCalloc(1, TSDB_TABLE_NAME_LEN, true);
170✔
2337
    snprintf(tbName, TSDB_TABLE_NAME_LEN, "%s%" PRIu64,
171✔
2338
             stbInfo->childTblPrefix, start_table_from + tbSeq);
2339
    char *tagName = benchCalloc(1, TSDB_MAX_TAGS, true);
171✔
2340
    for (int i = 0; i < stbInfo->tags->size; i++) {
1,557✔
2341
        Field * tag = benchArrayGet(stbInfo->tags, i);
1,387✔
2342
        snprintf(tagName, TSDB_MAX_TAGS, "t%d", i);
1,386✔
2343
        switch (tag->type) {
1,386✔
2344
            case TSDB_DATA_TYPE_BOOL: {
153✔
2345
                bool boolTmp = tmpBool(tag);
153✔
2346
                tools_cJSON_AddNumberToObject(tags, tagName, boolTmp);
153✔
2347
                break;
153✔
2348
            }
2349
            case TSDB_DATA_TYPE_FLOAT: {
153✔
2350
                float floatTmp = tmpFloat(tag);
153✔
2351
                tools_cJSON_AddNumberToObject(tags, tagName, floatTmp);
153✔
2352
                break;
152✔
2353
            }
2354
            case TSDB_DATA_TYPE_DOUBLE: {
153✔
2355
                double doubleTmp = tmpDouble(tag);
153✔
2356
                tools_cJSON_AddNumberToObject(tags, tagName, doubleTmp);
152✔
2357
                break;
152✔
2358
            }
2359

2360
            case TSDB_DATA_TYPE_BINARY:
306✔
2361
            case TSDB_DATA_TYPE_VARBINARY:
2362
            case TSDB_DATA_TYPE_NCHAR: {
2363
                char *buf = (char *)benchCalloc(tag->length + 1, 1, false);
306✔
2364
                rand_string(buf, tag->length, g_arguments->chinese);
306✔
2365
                if (tag->type == TSDB_DATA_TYPE_BINARY || tag->type == TSDB_DATA_TYPE_VARBINARY) {
306!
2366
                    tools_cJSON_AddStringToObject(tags, tagName, buf);
154✔
2367
                } else {
2368
                    tools_cJSON_AddStringToObject(tags, tagName, buf);
152✔
2369
                }
2370
                tmfree(buf);
306✔
2371
                break;
306✔
2372
            }
2373
            default: {
621✔
2374
                int tagTmp = tag->min;
621✔
2375
                if (tag->max != tag->min) {
621!
2376
                    tagTmp += (taosRandom() % (tag->max - tag->min));
624✔
2377
                }
2378
                tools_cJSON_AddNumberToObject(
623✔
2379
                        tags, tagName, tagTmp);
2380
                break;
624✔
2381
            }
2382
        }
2383
    }
2384
    tools_cJSON_AddItemToArray(tagsList, tags);
170✔
2385
    debugPrintJsonNoTime(tags);
170!
2386
    char *tags_text = tools_cJSON_PrintUnformatted(tags);
170✔
2387
    debugPrintNoTimestamp("%s() LN%d, No.%"PRIu64" table's tags text: %s\n",
171!
2388
                          __func__, __LINE__,
2389
                          start_table_from + tbSeq, tags_text);
2390
    sml_tags_json_array[tbSeq] = tags_text;
171✔
2391
    tmfree(tagName);
171✔
2392
    tmfree(tbName);
171✔
2393
}
171✔
2394

2395
void generateSmlTaosJsonTags(tools_cJSON *tagsList, SSuperTable *stbInfo,
75✔
2396
                            uint64_t start_table_from, int tbSeq) {
2397
    tools_cJSON * tags = tools_cJSON_CreateObject();
75✔
2398
    char *  tbName = benchCalloc(1, TSDB_TABLE_NAME_LEN, true);
75✔
2399
    snprintf(tbName, TSDB_TABLE_NAME_LEN, "%s%" PRIu64,
75✔
2400
             stbInfo->childTblPrefix, tbSeq + start_table_from);
2401
    tools_cJSON_AddStringToObject(tags, "id", tbName);
75✔
2402
    char *tagName = benchCalloc(1, TSDB_MAX_TAGS, true);
75✔
2403
    for (int i = 0; i < stbInfo->tags->size; i++) {
734✔
2404
        Field * tag = benchArrayGet(stbInfo->tags, i);
660✔
2405
        tools_cJSON *tagObj = tools_cJSON_CreateObject();
659✔
2406
        snprintf(tagName, TSDB_MAX_TAGS, "t%d", i);
660✔
2407
        switch (tag->type) {
660✔
2408
            case TSDB_DATA_TYPE_BOOL: {
73✔
2409
                bool boolTmp = tmpBool(tag);
73✔
2410
                tools_cJSON_AddBoolToObject(tagObj, "value", boolTmp);
73✔
2411
                tools_cJSON_AddStringToObject(tagObj, "type", "bool");
73✔
2412
                break;
73✔
2413
            }
2414
            case TSDB_DATA_TYPE_FLOAT: {
73✔
2415
                float floatTmp = tmpFloat(tag);
73✔
2416
                tools_cJSON_AddNumberToObject(tagObj, "value", floatTmp);
73✔
2417
                tools_cJSON_AddStringToObject(tagObj, "type", "float");
73✔
2418
                break;
73✔
2419
            }
2420
            case TSDB_DATA_TYPE_DOUBLE: {
73✔
2421
                double doubleTmp = tmpDouble(tag);
73✔
2422
                tools_cJSON_AddNumberToObject(tagObj, "value", doubleTmp);
73✔
2423
                tools_cJSON_AddStringToObject(tagObj, "type", "double");
73✔
2424
                break;
73✔
2425
            }
2426

2427
            case TSDB_DATA_TYPE_BINARY:
148✔
2428
            case TSDB_DATA_TYPE_VARBINARY:
2429
            case TSDB_DATA_TYPE_NCHAR: {
2430
                char *buf = (char *)benchCalloc(tag->length + 1, 1, false);
148✔
2431
                rand_string(buf, tag->length, g_arguments->chinese);
148✔
2432
                if (tag->type == TSDB_DATA_TYPE_BINARY || tag->type == TSDB_DATA_TYPE_VARBINARY) {
148!
2433
                    tools_cJSON_AddStringToObject(tagObj, "value", buf);
75✔
2434
                    tools_cJSON_AddStringToObject(tagObj, "type", "binary");
75✔
2435
                } else {
2436
                    tools_cJSON_AddStringToObject(tagObj, "value", buf);
73✔
2437
                    tools_cJSON_AddStringToObject(tagObj, "type", "nchar");
73✔
2438
                }
2439
                tmfree(buf);
148✔
2440
                break;
148✔
2441
            }
2442
            default: {
293✔
2443
                int64_t tagTmp = tag->min;
293✔
2444
                if (tag->max != tag->min) {
293✔
2445
                    tagTmp += (taosRandom() % (tag->max - tag->min));
288✔
2446
                }
2447
                tools_cJSON_AddNumberToObject(tagObj, "value", tagTmp);
295✔
2448
                        tools_cJSON_AddStringToObject(tagObj, "type",
294✔
2449
                                        convertDatatypeToString(tag->type));
2450
                break;
294✔
2451
            }
2452
        }
2453
        tools_cJSON_AddItemToObject(tags, tagName, tagObj);
661✔
2454
    }
2455
    tools_cJSON_AddItemToArray(tagsList, tags);
74✔
2456
    tmfree(tagName);
74✔
2457
    tmfree(tbName);
74✔
2458
}
75✔
2459

2460
void generateSmlJsonValues(
147✔
2461
        char **sml_json_value_array, SSuperTable *stbInfo, int tableSeq) {
2462
    char *value_buf = NULL;
147✔
2463
    Field* col = benchArrayGet(stbInfo->cols, 0);
147✔
2464
    int len_key = strlen("\"value\":,");
147✔
2465
    switch (col->type) {
147!
2466
        case TSDB_DATA_TYPE_BOOL: {
8✔
2467
            bool boolTmp = tmpBool(col);
8✔
2468
            value_buf = benchCalloc(len_key + 6, 1, true);
8✔
2469
            snprintf(value_buf, len_key + 6,
8✔
2470
                     "\"value\":%s,", boolTmp?"true":"false");
2471
            break;
8✔
2472
        }
2473
        case TSDB_DATA_TYPE_FLOAT: {
18✔
2474
            value_buf = benchCalloc(len_key + 20, 1, true);
18✔
2475
            float floatTmp = tmpFloat(col);
18✔
2476
            snprintf(value_buf, len_key + 20,
18✔
2477
                     "\"value\":%f,", floatTmp);
2478
            break;
18✔
2479
        }
2480
        case TSDB_DATA_TYPE_DOUBLE: {
16✔
2481
            value_buf = benchCalloc(len_key + 40, 1, true);
16✔
2482
            double doubleTmp = tmpDouble(col);
16✔
2483
            snprintf(
16✔
2484
                value_buf, len_key + 40, "\"value\":%f,", doubleTmp);
16✔
2485
            break;
16✔
2486
        }
2487
        case TSDB_DATA_TYPE_BINARY:
32✔
2488
        case TSDB_DATA_TYPE_VARBINARY:
2489
        case TSDB_DATA_TYPE_NCHAR: {
2490
            char *buf = (char *)benchCalloc(col->length + 1, 1, false);
32✔
2491
            rand_string(buf, col->length, g_arguments->chinese);
32✔
2492
            value_buf = benchCalloc(len_key + col->length + 3, 1, true);
32✔
2493
            snprintf(value_buf, len_key + col->length + 3,
32✔
2494
                     "\"value\":\"%s\",", buf);
2495
            tmfree(buf);
32✔
2496
            break;
32✔
2497
        }
2498
        case TSDB_DATA_TYPE_GEOMETRY: {
×
2499
            char *buf = (char *)benchCalloc(col->length + 1, 1, false);
×
2500
            tmpGeometry(buf, stbInfo->iface, col, 0);
×
2501
            value_buf = benchCalloc(len_key + col->length + 3, 1, true);
×
2502
            snprintf(value_buf, len_key + col->length + 3,
×
2503
                     "\"value\":\"%s\",", buf);
2504
            tmfree(buf);
×
2505
            break;
×
2506
        }
2507
        default: {
73✔
2508
            value_buf = benchCalloc(len_key + 20, 1, true);
73✔
2509
            double doubleTmp = tmpDouble(col);
73✔
2510
            snprintf(value_buf, len_key + 20, "\"value\":%f,", doubleTmp);
73✔
2511
            break;
73✔
2512
        }
2513
    }
2514
    sml_json_value_array[tableSeq] = value_buf;
147✔
2515
}
147✔
2516

2517
void generateSmlJsonCols(tools_cJSON *array, tools_cJSON *tag,
479✔
2518
                         SSuperTable *stbInfo,
2519
                            uint32_t time_precision, int64_t timestamp) {
2520
    tools_cJSON * record = tools_cJSON_CreateObject();
479✔
2521
    tools_cJSON_AddNumberToObject(record, "timestamp", (double)timestamp);
480✔
2522
    Field* col = benchArrayGet(stbInfo->cols, 0);
479✔
2523
    switch (col->type) {
480!
2524
        case TSDB_DATA_TYPE_BOOL: {
160✔
2525
            bool boolTmp = tmpBool(col);
160✔
2526
            tools_cJSON_AddBoolToObject(record, "value", boolTmp);
160✔
2527
            break;
160✔
2528
        }
2529
        case TSDB_DATA_TYPE_FLOAT: {
×
2530
            float floatTmp = tmpFloat(col);
×
2531
            tools_cJSON_AddNumberToObject(record, "value", floatTmp);
×
2532
            break;
×
2533
        }
2534
        case TSDB_DATA_TYPE_DOUBLE: {
×
2535
            double doubleTmp = tmpDouble(col);
×
2536
            tools_cJSON_AddNumberToObject(record, "value", doubleTmp);
×
2537
            break;
×
2538
        }
2539
        case TSDB_DATA_TYPE_BINARY:
×
2540
        case TSDB_DATA_TYPE_VARBINARY:
2541
        case TSDB_DATA_TYPE_NCHAR: {
2542
            char *buf = (char *)benchCalloc(col->length + 1, 1, false);
×
2543
            rand_string(buf, col->length, g_arguments->chinese);
×
2544
            if (col->type == TSDB_DATA_TYPE_BINARY) {
×
2545
                tools_cJSON_AddStringToObject(record, "value", buf);
×
2546
            } else {
2547
                tools_cJSON_AddStringToObject(record, "value", buf);
×
2548
            }
2549
            tmfree(buf);
×
2550
            break;
×
2551
        }
2552
        case TSDB_DATA_TYPE_GEOMETRY: {
×
2553
            char *buf = (char *)benchCalloc(col->length + 1, 1, false);
×
2554
            tmpGeometry(buf, stbInfo->iface, col, 0);
×
2555
            tools_cJSON_AddStringToObject(record, "value", buf);
×
2556
            tmfree(buf);
×
2557
            break;
×
2558
        }
2559
        default: {
320✔
2560
            double doubleTmp = tmpDouble(col);
320✔
2561
            tools_cJSON_AddNumberToObject(record, "value", doubleTmp);
320✔
2562
            break;
320✔
2563
        }
2564
    }
2565
    tools_cJSON_AddItemToObject(record, "tags", tag);
480✔
2566
    tools_cJSON_AddStringToObject(record, "metric", stbInfo->stbName);
480✔
2567
    tools_cJSON_AddItemToArray(array, record);
480✔
2568
}
480✔
2569

2570
void generateSmlTaosJsonCols(tools_cJSON *array, tools_cJSON *tag,
1,451✔
2571
                         SSuperTable *stbInfo,
2572
                            uint32_t time_precision, int64_t timestamp) {
2573
    tools_cJSON * record = tools_cJSON_CreateObject();
1,451✔
2574
    tools_cJSON * ts = tools_cJSON_CreateObject();
1,452✔
2575
    tools_cJSON_AddNumberToObject(ts, "value", (double)timestamp);
1,451✔
2576
    if (time_precision == TSDB_SML_TIMESTAMP_MILLI_SECONDS) {
1,451!
2577
        tools_cJSON_AddStringToObject(ts, "type", "ms");
1,451✔
2578
    } else if (time_precision == TSDB_SML_TIMESTAMP_MICRO_SECONDS) {
×
2579
        tools_cJSON_AddStringToObject(ts, "type", "us");
×
2580
    } else if (time_precision == TSDB_SML_TIMESTAMP_NANO_SECONDS) {
×
2581
        tools_cJSON_AddStringToObject(ts, "type", "ns");
×
2582
    }
2583
    tools_cJSON *value = tools_cJSON_CreateObject();
1,451✔
2584
    Field* col = benchArrayGet(stbInfo->cols, 0);
1,452✔
2585
    switch (col->type) {
1,451!
2586
        case TSDB_DATA_TYPE_BOOL: {
160✔
2587
            bool boolTmp = tmpBool(col);
160✔
2588
            tools_cJSON_AddBoolToObject(value, "value", boolTmp);
160✔
2589
            tools_cJSON_AddStringToObject(value, "type", "bool");
160✔
2590
            break;
160✔
2591
        }
2592
        case TSDB_DATA_TYPE_FLOAT: {
162✔
2593
            float floatTmp = tmpFloat(col);
162✔
2594
            tools_cJSON_AddNumberToObject(value, "value", floatTmp);
162✔
2595
            tools_cJSON_AddStringToObject(value, "type", "float");
162✔
2596
            break;
161✔
2597
        }
2598
        case TSDB_DATA_TYPE_DOUBLE: {
160✔
2599
            double dblTmp = tmpDouble(col);
160✔
2600
            tools_cJSON_AddNumberToObject(value, "value", dblTmp);
160✔
2601
            tools_cJSON_AddStringToObject(value, "type", "double");
160✔
2602
            break;
160✔
2603
        }
2604
        case TSDB_DATA_TYPE_BINARY:
330✔
2605
        case TSDB_DATA_TYPE_VARBINARY:
2606
        case TSDB_DATA_TYPE_NCHAR: {
2607
            char *buf = (char *)benchCalloc(col->length + 1, 1, false);
330✔
2608
            rand_string(buf, col->length, g_arguments->chinese);
330✔
2609
            if (col->type == TSDB_DATA_TYPE_BINARY || col->type == TSDB_DATA_TYPE_VARBINARY) {
330!
2610
                tools_cJSON_AddStringToObject(value, "value", buf);
160✔
2611
                tools_cJSON_AddStringToObject(value, "type", "binary");
160✔
2612
            } else {
2613
                tools_cJSON_AddStringToObject(value, "value", buf);
170✔
2614
                tools_cJSON_AddStringToObject(value, "type", "nchar");
170✔
2615
            }
2616
            tmfree(buf);
330✔
2617
            break;
330✔
2618
        }
2619
        case TSDB_DATA_TYPE_GEOMETRY: {
×
2620
            char *buf = (char *)benchCalloc(col->length + 1, 1, false);
×
2621
            tmpGeometry(buf, stbInfo->iface, col, 0);
×
2622
            tools_cJSON_AddStringToObject(value, "value", buf);
×
2623
            tools_cJSON_AddStringToObject(value, "type", "geometry");
×
2624
            tmfree(buf);
×
2625
        }
2626
        default: {
640✔
2627
            double dblTmp = (double)col->min;
640✔
2628
            if (col->max != col->min) {
640!
2629
                dblTmp += (double)((taosRandom() % (col->max - col->min)));
640✔
2630
            }
2631
            tools_cJSON_AddNumberToObject(value, "value", dblTmp);
640✔
2632
            tools_cJSON_AddStringToObject(
639✔
2633
                    value, "type", convertDatatypeToString(col->type));
2634
            break;
640✔
2635
        }
2636
    }
2637
    tools_cJSON_AddItemToObject(record, "timestamp", ts);
1,451✔
2638
    tools_cJSON_AddItemToObject(record, "value", value);
1,452✔
2639
    tools_cJSON_AddItemToObject(record, "tags", tag);
1,451✔
2640
    tools_cJSON_AddStringToObject(record, "metric", stbInfo->stbName);
1,452✔
2641
    tools_cJSON_AddItemToArray(array, record);
1,450✔
2642
}
1,449✔
2643

2644
// generateTag data from random or csv file
2645
bool generateTagData(SSuperTable *stbInfo, char *buf, int64_t cnt, FILE* csv, BArray* tagsStmt, int64_t loopBegin) {
2,087✔
2646
    if(csv) {
2,087✔
2647
        if (generateSampleFromCsv(
17!
2648
                buf, NULL, csv,
2649
                stbInfo->lenOfTags,
17✔
2650
                cnt)) {
2651
            return false;
×
2652
        }
2653
    } else {
2654
        if (generateRandData(stbInfo,
4,140!
2655
                            buf,
2656
                            cnt * stbInfo->lenOfTags,
2,070✔
2657
                            stbInfo->lenOfTags,
2,070✔
2658
                            tagsStmt ? tagsStmt : stbInfo->tags,
2659
                            cnt, true, NULL, loopBegin)) {
2660
            errorPrint("Generate Tag Rand Data Failed. stb=%s\n", stbInfo->stbName);
×
2661
            return false;
×
2662
        }
2663
    }
2664

2665
    return true;
2,087✔
2666
}
2667

2668
static int seekFromCsv(FILE* fp, int64_t seek) {
17✔
2669
    size_t  n = 0;
17✔
2670
    char *  line = NULL;
17✔
2671

2672
    if (seek > 0) {
17✔
2673
        for (size_t i = 0; i < seek; i++){
34✔
2674
            ssize_t readLen = 0;
26✔
2675
#if defined(WIN32) || defined(WIN64)
2676
            toolsGetLineFile(&line, &n, fp);
2677
            readLen = n;
2678
            if (0 == readLen) {
2679
#else
2680
            readLen = getline(&line, &n, fp);
26✔
2681
            if (-1 == readLen) {
26✔
2682
#endif
2683
                if (0 != fseek(fp, 0, SEEK_SET)) {
5!
2684
                    return -1;
×
2685
                }
2686
                continue;
5✔
2687
            }           
2688
        }
2689
    }
2690

2691
    tmfree(line);
17✔
2692
    infoPrint("seek data from csv file, seek rows=%" PRId64 "\n", seek);
17✔
2693
    return 0;
17✔
2694
}
2695

2696
// open tag from csv file
2697
FILE* openTagCsv(SSuperTable* stbInfo, uint64_t seek) {
1,313✔
2698
    FILE* csvFile = NULL;
1,313✔
2699
    if (stbInfo->tagsFile[0] != 0) {
1,313✔
2700
        csvFile = fopen(stbInfo->tagsFile, "r");
17✔
2701
        if (csvFile == NULL) {
17!
2702
            errorPrint("Failed to open tag sample file: %s, reason:%s\n", stbInfo->tagsFile, strerror(errno));
×
2703
            return NULL;
×
2704
        }
2705
        
2706
        if (seekFromCsv(csvFile, seek)) {
17!
2707
            fclose(csvFile);
×
2708
            errorPrint("Failed to seek csv file: %s, reason:%s\n", stbInfo->tagsFile, strerror(errno));
×
2709
            return NULL;
×
2710

2711
        }
2712
        infoPrint("open tag csv file :%s \n", stbInfo->tagsFile);
17✔
2713
        
2714
    }
2715
    return csvFile;
1,318✔
2716
}
2717

2718
//
2719
// STMT2 bind cols param progressive
2720
//
2721
uint32_t bindVColsProgressive(TAOS_STMT2_BINDV *bindv, int32_t tbIndex,
116✔
2722
                 threadInfo *pThreadInfo,
2723
                 uint32_t batch, int64_t startTime, int64_t pos,
2724
                 SChildTable *childTbl, int32_t *pkCur, int32_t *pkCnt, int32_t *n) {
2725
    
2726
    SSuperTable *stbInfo = pThreadInfo->stbInfo;
116✔
2727
    uint32_t     columnCount = stbInfo->cols->size;
116✔
2728

2729
    // clear
2730
    memset(pThreadInfo->bindParams, 0, sizeof(TAOS_STMT2_BIND) * (columnCount + 1));
116✔
2731
    debugPrint("stmt2 bindVColsProgressive child=%s batch=%d pos=%" PRId64 "\n", childTbl->name, batch, pos);
116!
2732
    // loop cols
2733
    for (int c = 0; c <= columnCount; c++) {
608✔
2734
        // des
2735
        TAOS_STMT2_BIND *param = (TAOS_STMT2_BIND *)(pThreadInfo->bindParams + sizeof(TAOS_STMT2_BIND) * c);
493✔
2736
        char data_type;
2737
        int32_t length = 0;
493✔
2738
        if (c == 0) {
493✔
2739
            data_type = TSDB_DATA_TYPE_TIMESTAMP;
115✔
2740
            if (stbInfo->useSampleTs) {
115!
2741
                param->buffer = pThreadInfo->bind_ts_array + pos;
×
2742
            } else {
2743
                param->buffer = pThreadInfo->bind_ts_array;
115✔
2744
            }
2745
            length = sizeof(int64_t);
115✔
2746
        } else {
2747
            Field *col = benchArrayGet(stbInfo->cols, c - 1);
378✔
2748
            data_type = col->type;
379✔
2749
            length    = col->length;
379✔
2750
            if (childTbl->useOwnSample) {
379✔
2751
                ChildField *childCol = benchArrayGet(childTbl->childCols, c-1);
22✔
2752
                param->buffer = (char *)childCol->stmtData.data + pos * col->length;
23✔
2753
                param->is_null = childCol->stmtData.is_null + pos;
23✔
2754
            } else {
2755
                param->buffer = (char *)col->stmtData.data + pos * col->length;
357✔
2756
                param->is_null = col->stmtData.is_null + pos;
357✔
2757
            }
2758
            debugPrint("col[%d]: type: %s, len: %d\n", c,
380!
2759
                    convertDatatypeToString(data_type),
2760
                    col->length);
2761
        }
2762
        param->buffer_type = data_type;
493✔
2763
        param->length = pThreadInfo->lengths[c];
493✔
2764

2765
        for (int b = 0; b < batch; b++) {
90,165✔
2766
            param->length[b] = length;
89,672✔
2767
        }
2768
        param->num = batch;
493✔
2769
    }
2770
    
2771
    // ts key
2772
    if (!stbInfo->useSampleTs) {
115!
2773
        // set first column ts array values
2774
        for (uint32_t k = 0; k < batch; k++) {
15,404✔
2775
            /* columnCount + 1 (ts) */
2776
            if (stbInfo->disorderRatio) {
15,287!
2777
                *(pThreadInfo->bind_ts_array + k) =
×
2778
                    startTime + getTSRandTail(stbInfo->timestamp_step, *n,
×
2779
                                            stbInfo->disorderRatio,
2780
                                            stbInfo->disorderRange);
2781
            } else {
2782
                *(pThreadInfo->bind_ts_array + k) = startTime + stbInfo->timestamp_step * (*n);
15,287✔
2783
            }
2784

2785
            // check n need add
2786
            if (!stbInfo->primary_key || needChangeTs(stbInfo, pkCur, pkCnt)) {
15,287!
2787
                *n = *n + 1;
15,278✔
2788
            }
2789
        }
2790
    }
2791

2792
    // set to bindv (only one table, so always is 0 index table)
2793
    bindv->bind_cols[tbIndex] = (TAOS_STMT2_BIND *)pThreadInfo->bindParams;
115✔
2794
    return batch;
115✔
2795
}
2796

2797

2798
//
2799
// STMT2 bind tags param progressive
2800
//
2801
uint32_t bindVTags(TAOS_STMT2_BINDV *bindv, int32_t tbIndex, int32_t w, BArray* fields) {
×
2802

2803
    TAOS_STMT2_BIND *tagsTb = bindv->tags[tbIndex];
×
2804

2805
    // loop 
2806
    for (int32_t i = 0; i < fields->size; i++) {
×
2807
        Field* field = benchArrayGet(fields, i);
×
2808

2809
        // covert field data to bind struct
2810
        tagsTb[i].buffer      = (char *)(field->stmtData.data) + field->length * w ;
×
2811
        tagsTb[i].buffer_type = field->type;
×
2812
        tagsTb[i].is_null     = field->stmtData.is_null;
×
2813
        if (IS_VAR_DATA_TYPE(field->type)) {
×
2814
            // only var set length
2815
            tagsTb[i].length  = field->stmtData.lengths;
×
2816
        }
2817

2818
        // tag always one line
2819
        tagsTb[i].num = 1;
×
2820
    }
2821
    
2822
    return 1;
×
2823
}
2824

2825
//
2826
// STMT2 bind cols param progressive
2827
//
2828
uint32_t bindVColsInterlace(TAOS_STMT2_BINDV *bindv, int32_t tbIndex,
510✔
2829
                 threadInfo *pThreadInfo,
2830
                 uint32_t batch, int64_t startTime, int64_t pos,
2831
                 SChildTable *childTbl, int32_t *pkCur, int32_t *pkCnt, int32_t *n) {
2832
    // count
2833
    bindv->count += 1;
510✔
2834
    // info
2835
    SSuperTable *stbInfo    = pThreadInfo->stbInfo;
510✔
2836
    TAOS_STMT2_BIND *colsTb = bindv->bind_cols[tbIndex];
510✔
2837
    BArray* fields          = stbInfo->cols;
510✔
2838

2839

2840
    // loop 
2841
    for (int32_t i = 0; i < fields->size + 1; i++) {
8,202✔
2842
        // col bind
2843
        if (i == 0) {
7,693✔
2844
            // ts 
2845
            colsTb[i].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
510✔
2846
            colsTb[i].length      = pThreadInfo->lengths[0];
510✔
2847
            for (int32_t j = 0; j < batch; j++) {
1,019✔
2848
                colsTb[i].length[j] = sizeof(int64_t); 
509✔
2849
            }
2850
            if (stbInfo->useSampleTs) {
510!
2851
                colsTb[i].buffer = pThreadInfo->bind_ts_array + pos;
×
2852
            } else {
2853
                colsTb[i].buffer = pThreadInfo->bind_ts_array;
510✔
2854
            }
2855
            // no need set is_null for main key
2856
        } else {
2857
            Field* field = benchArrayGet(fields, i - 1);
7,183✔
2858
            colsTb[i].buffer_type = field->type;
7,172✔
2859

2860
            if (childTbl->useOwnSample) {
7,172!
2861
                ChildField *childCol = benchArrayGet(childTbl->childCols, i - 1);
×
2862
                colsTb[i].buffer  = (char *)childCol->stmtData.data + pos * field->length;
×
2863
                colsTb[i].is_null = childCol->stmtData.is_null + pos;
×
2864
                colsTb[i].length  = childCol->stmtData.lengths + pos;
×
2865
            } else {
2866
                colsTb[i].buffer  = (char *)field->stmtData.data + pos * field->length;
7,182✔
2867
                colsTb[i].is_null = field->stmtData.is_null + pos;
7,182✔
2868
                colsTb[i].length  = field->stmtData.lengths + pos;
7,182✔
2869
            }
2870
        }
2871

2872
        // set batch
2873
        colsTb[i].num = batch;
7,692✔
2874
    }
2875

2876
    // ts key
2877
    if (!stbInfo->useSampleTs) {
509!
2878
        // set first column ts array values
2879
        for (uint32_t k = 0; k < batch; k++) {
1,022✔
2880
            /* columnCount + 1 (ts) */
2881
            if (stbInfo->disorderRatio) {
511!
2882
                *(pThreadInfo->bind_ts_array + k) =
×
2883
                    startTime + getTSRandTail(stbInfo->timestamp_step, *n,
×
2884
                                            stbInfo->disorderRatio,
2885
                                            stbInfo->disorderRange);
2886
            } else {
2887
                *(pThreadInfo->bind_ts_array + k) = startTime + stbInfo->timestamp_step * (*n);
511✔
2888
            }
2889

2890
            // check n need add
2891
            if (!stbInfo->primary_key || needChangeTs(stbInfo, pkCur, pkCnt)) {
511!
2892
                *n = *n + 1;
511✔
2893
            }
2894
        }
2895
    }    
2896
    
2897
    return batch;
509✔
2898
}
2899

2900
// early malloc tags for stmt
2901
void prepareTagsStmt(SSuperTable* stbInfo) {
5✔
2902
    BArray *fields = stbInfo->tags;
5✔
2903
    int32_t loop   = TAG_BATCH_COUNT;
5✔
2904
    for (int i = 0; i < fields->size; ++i) {
37✔
2905
        Field *field = benchArrayGet(fields, i);
32✔
2906
        if (field->stmtData.data == NULL) {
32!
2907
            // data
2908
            if (field->type == TSDB_DATA_TYPE_BINARY
32✔
2909
                    || field->type == TSDB_DATA_TYPE_NCHAR) {
30✔
2910
                field->stmtData.data = benchCalloc(1, loop * (field->length + 1), true);
4✔
2911
            } else {
2912
                field->stmtData.data = benchCalloc(1, loop * field->length, true);
28✔
2913
            }
2914

2915
            // is_null
2916
            field->stmtData.is_null = benchCalloc(sizeof(char), loop, true);
32✔
2917
            // lengths
2918
            field->stmtData.lengths = benchCalloc(sizeof(int32_t), loop, true);
32✔
2919

2920
            // log
2921
            debugPrint("i=%d prepareTags fields=%p %s malloc stmtData.data=%p\n", i, fields, field->name ,field->stmtData.data);
32!
2922
        }
2923
    }
2924
}
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc