taosdemo.c 243.2 KB
Newer Older
S
TD-1057  
Shengliang Guan 已提交
1
/*
H
hzcheng 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

16 17 18 19 20

/*
   when in some thread query return error, thread don't exit, but return, otherwise coredump in other thread.
*/

21
#include <stdint.h>
S
slguan 已提交
22
#define _GNU_SOURCE
23 24
#define CURL_STATICLIB

S
TD-1057  
Shengliang Guan 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#ifdef LINUX
  #include <argp.h>
  #include <inttypes.h>
  #ifndef _ALPINE
    #include <error.h>
  #endif
  #include <pthread.h>
  #include <semaphore.h>
  #include <stdbool.h>
  #include <stdio.h>
  #include <string.h>
  #include <sys/time.h>
  #include <time.h>
  #include <unistd.h>
  #include <wordexp.h>
  #include <regex.h>
41
#else
S
TD-1057  
Shengliang Guan 已提交
42 43
  #include <regex.h>
  #include <stdio.h>
44
#endif
H
hzcheng 已提交
45

46
#include <assert.h>
47
#include <stdlib.h>
48 49
#include "cJSON.h"

50
#include "os.h"
H
hzcheng 已提交
51
#include "taos.h"
52
#include "taoserror.h"
H
Hui Li 已提交
53
#include "tutil.h"
S
slguan 已提交
54

55 56 57
#define REQ_EXTRA_BUF_LEN   1024
#define RESP_BUF_LEN        4096

S
slguan 已提交
58 59
extern char configDir[];

60 61 62 63
#define INSERT_JSON_NAME      "insert.json"
#define QUERY_JSON_NAME       "query.json"
#define SUBSCRIBE_JSON_NAME   "subscribe.json"

64 65 66 67 68 69
enum TEST_MODE {
    INSERT_TEST,            // 0
    QUERY_TEST,             // 1
    SUBSCRIBE_TEST,         // 2
    INVAID_TEST
};
70

71 72
#define MAX_RECORDS_PER_REQ     32766

73 74
#define MAX_SQL_SIZE       65536
#define BUFFER_SIZE        (65536*2)
75
#define COND_BUF_LEN        BUFFER_SIZE - 30
76 77
#define MAX_USERNAME_SIZE  64
#define MAX_PASSWORD_SIZE  64
78
#define MAX_DB_NAME_SIZE   64
79
#define MAX_HOSTNAME_SIZE  64
80
#define MAX_TB_NAME_SIZE   64
81
#define MAX_DATA_SIZE      (16*1024)+20     // max record len: 16*1024, timestamp string and ,('') need extra space
82 83 84 85 86 87 88 89 90 91
#define MAX_NUM_DATATYPE   10
#define OPT_ABORT          1 /* –abort */
#define STRING_LEN         60000
#define MAX_PREPARED_RAND  1000000
#define MAX_FILE_NAME_LEN  256

#define   MAX_SAMPLES_ONCE_FROM_FILE   10000
#define   MAX_NUM_DATATYPE 10

#define   MAX_DB_COUNT           8
92
#define   MAX_SUPER_TABLE_COUNT  200
93 94 95
#define   MAX_COLUMN_COUNT       1024
#define   MAX_TAG_COUNT          128

96
#define   MAX_QUERY_SQL_COUNT    100
97
#define   MAX_QUERY_SQL_LENGTH   1024
98 99

#define   MAX_DATABASE_COUNT     256
100
#define INPUT_BUF_LEN   256
101

102
#define DEFAULT_TIMESTAMP_STEP  1
103

104

105 106 107 108 109
typedef enum CREATE_SUB_TALBE_MOD_EN {
  PRE_CREATE_SUBTBL,
  AUTO_CREATE_SUBTBL,
  NO_CREATE_SUBTBL
} CREATE_SUB_TALBE_MOD_EN;
110

111 112
typedef enum TALBE_EXISTS_EN {
  TBL_NO_EXISTS,
113
  TBL_ALREADY_EXISTS,
114 115 116
  TBL_EXISTS_BUTT
} TALBE_EXISTS_EN;

117
enum enumSYNC_MODE {
118 119
  SYNC_MODE,
  ASYNC_MODE,
120 121
  MODE_BUT
};
122

123 124 125 126 127 128
typedef enum enumQUERY_CLASS {
    SPECIFIED_CLASS,
    STABLE_CLASS,
    CLASS_BUT
} QUERY_CLASS;

129 130 131 132 133 134
typedef enum enum_INSERT_MODE {
    PROGRESSIVE_INSERT_MODE,
    INTERLACE_INSERT_MODE,
    INVALID_INSERT_MODE
} INSERT_MODE;

135
typedef enum enumQUERY_TYPE {
136
  NO_INSERT_TYPE,
137
  INSERT_TYPE,
138
  QUERY_TYPE_BUT
139
} QUERY_TYPE;
140 141 142 143 144 145 146

enum _show_db_index {
  TSDB_SHOW_DB_NAME_INDEX,
  TSDB_SHOW_DB_CREATED_TIME_INDEX,
  TSDB_SHOW_DB_NTABLES_INDEX,
  TSDB_SHOW_DB_VGROUPS_INDEX,
  TSDB_SHOW_DB_REPLICA_INDEX,
147
  TSDB_SHOW_DB_QUORUM_INDEX,
148 149 150 151 152 153 154 155 156 157
  TSDB_SHOW_DB_DAYS_INDEX,
  TSDB_SHOW_DB_KEEP_INDEX,
  TSDB_SHOW_DB_CACHE_INDEX,
  TSDB_SHOW_DB_BLOCKS_INDEX,
  TSDB_SHOW_DB_MINROWS_INDEX,
  TSDB_SHOW_DB_MAXROWS_INDEX,
  TSDB_SHOW_DB_WALLEVEL_INDEX,
  TSDB_SHOW_DB_FSYNC_INDEX,
  TSDB_SHOW_DB_COMP_INDEX,
  TSDB_SHOW_DB_CACHELAST_INDEX,
158
  TSDB_SHOW_DB_PRECISION_INDEX,
159 160 161 162 163 164 165 166 167 168
  TSDB_SHOW_DB_UPDATE_INDEX,
  TSDB_SHOW_DB_STATUS_INDEX,
  TSDB_MAX_SHOW_DB
};

// -----------------------------------------SHOW TABLES CONFIGURE -------------------------------------
enum _show_stables_index {
  TSDB_SHOW_STABLES_NAME_INDEX,
  TSDB_SHOW_STABLES_CREATED_TIME_INDEX,
  TSDB_SHOW_STABLES_COLUMNS_INDEX,
169 170
  TSDB_SHOW_STABLES_METRIC_INDEX,
  TSDB_SHOW_STABLES_UID_INDEX,
171
  TSDB_SHOW_STABLES_TID_INDEX,
172
  TSDB_SHOW_STABLES_VGID_INDEX,
173
  TSDB_MAX_SHOW_STABLES
174 175
};

176 177 178 179 180 181 182 183 184 185 186 187 188 189
enum _describe_table_index {
  TSDB_DESCRIBE_METRIC_FIELD_INDEX,
  TSDB_DESCRIBE_METRIC_TYPE_INDEX,
  TSDB_DESCRIBE_METRIC_LENGTH_INDEX,
  TSDB_DESCRIBE_METRIC_NOTE_INDEX,
  TSDB_MAX_DESCRIBE_METRIC
};

typedef struct {
  char field[TSDB_COL_NAME_LEN + 1];
  char type[16];
  int length;
  char note[128];
} SColDes;
H
hzcheng 已提交
190 191

/* Used by main to communicate with parse_opt. */
192 193
static char *g_dupstr = NULL;

194 195
typedef struct SArguments_S {
  char *   metaFile;
196
  uint32_t test_mode;
197 198 199 200 201 202 203 204 205
  char *   host;
  uint16_t port;
  char *   user;
  char *   password;
  char *   database;
  int      replica;
  char *   tb_prefix;
  char *   sqlFile;
  bool     use_metric;
206
  bool     drop_database;
207
  bool     insert_only;
208
  bool     answer_yes;
209
  bool     debug_print;
210
  bool     verbose_print;
211
  bool     performance_print;
212
  char *   output_file;
213
  bool     async_mode;
214
  char *   datatype[MAX_NUM_DATATYPE + 1];
215 216 217 218
  uint32_t len_of_binary;
  uint32_t num_of_CPR;
  uint32_t num_of_threads;
  uint64_t insert_interval;
219
  int64_t  query_times;
220 221 222
  uint64_t interlace_rows;
  uint64_t num_of_RPR;                  // num_of_records_per_req
  uint64_t max_sql_len;
223 224
  int64_t  num_of_tables;
  int64_t  num_of_DPT;
225
  int      abort;
226 227
  int      disorderRatio;               // 0: no disorder, >0: x%
  int      disorderRange;               // ms or us by database precision
228
  uint32_t method_of_delete;
229
  char **  arg_list;
230 231
  uint64_t totalInsertRows;
  uint64_t totalAffectedRows;
232 233 234
} SArguments;

typedef struct SColumn_S {
235 236 237
  char      field[TSDB_COL_NAME_LEN + 1];
  char      dataType[MAX_TB_NAME_SIZE];
  uint32_t  dataLen;
238
  char      note[128];
239 240 241
} StrColumn;

typedef struct SSuperTable_S {
242
  char         sTblName[MAX_TB_NAME_SIZE+1];
243
  int64_t      childTblCount;
244
  bool         childTblExists;          // 0: no, 1: yes
245 246
  uint64_t     batchCreateTableNum;     // 0: no batch,  > 0: batch table number in one sql
  uint8_t      autoCreateTable;         // 0: create sub table, 1: auto create sub table
247
  char         childTblPrefix[MAX_TB_NAME_SIZE];
248
  char         dataSource[MAX_TB_NAME_SIZE+1];  // rand_gen or sample
249
  char         insertMode[MAX_TB_NAME_SIZE];    // taosc, rest
250
  int64_t      childTblLimit;
251
  uint64_t     childTblOffset;
252

253
//  int          multiThreadWriteOneTbl;  // 0: no, 1: yes
254
  uint64_t     interlaceRows;           //
255 256
  int          disorderRatio;           // 0: no disorder, >0: x%
  int          disorderRange;           // ms or us by database precision
257
  uint64_t     maxSqlLen;               //
258

259
  uint64_t     insertInterval;          // insert interval, will override global insert interval
260
  int64_t      insertRows;
261
  int64_t      timeStampStep;
262
  char         startTimestamp[MAX_TB_NAME_SIZE];
263
  char         sampleFormat[MAX_TB_NAME_SIZE];  // csv, json
264 265
  char         sampleFile[MAX_FILE_NAME_LEN+1];
  char         tagsFile[MAX_FILE_NAME_LEN+1];
266

267
  uint32_t     columnCount;
268
  StrColumn    columns[MAX_COLUMN_COUNT];
269
  uint32_t     tagCount;
270 271 272
  StrColumn    tags[MAX_TAG_COUNT];

  char*        childTblName;
273
  char*        colsOfCreateChildTable;
274 275
  uint64_t     lenOfOneRow;
  uint64_t     lenOfTagOfOneRow;
276 277 278 279 280

  char*        sampleDataBuf;
  //int          sampleRowCount;
  //int          sampleUsePos;

281
  uint32_t     tagSource;    // 0: rand, 1: tag sample
282
  char*        tagDataBuf;
283 284
  uint32_t     tagSampleCount;
  uint32_t     tagUsePos;
285

286
  // statistics
287 288
  uint64_t     totalInsertRows;
  uint64_t     totalAffectedRows;
289 290 291 292 293
} SSuperTable;

typedef struct {
  char     name[TSDB_DB_NAME_LEN + 1];
  char     create_time[32];
294
  int64_t  ntables;
295
  int32_t  vgroups;
296 297
  int16_t  replica;
  int16_t  quorum;
298
  int16_t  days;
299 300 301 302 303 304 305 306 307 308 309 310 311 312
  char     keeplist[32];
  int32_t  cache; //MB
  int32_t  blocks;
  int32_t  minrows;
  int32_t  maxrows;
  int8_t   wallevel;
  int32_t  fsync;
  int8_t   comp;
  int8_t   cachelast;
  char     precision[8];   // time resolution
  int8_t   update;
  char     status[16];
} SDbInfo;

313
typedef struct SDbCfg_S {
314
//  int       maxtablesPerVnode;
315 316
  uint32_t  minRows;        // 0 means default
  uint32_t  maxRows;        // 0 means default
317 318
  int       comp;
  int       walLevel;
319
  int       cacheLast;
320
  int       fsync;
321 322 323 324 325 326 327
  int       replica;
  int       update;
  int       keep;
  int       days;
  int       cache;
  int       blocks;
  int       quorum;
328
  char      precision[MAX_TB_NAME_SIZE];
329 330 331 332
} SDbCfg;

typedef struct SDataBase_S {
  char         dbName[MAX_DB_NAME_SIZE];
333
  bool         drop;  // 0: use exists, 1: if exists, drop then new create
334
  SDbCfg       dbCfg;
335
  uint64_t     superTblCount;
336 337 338 339
  SSuperTable  superTbls[MAX_SUPER_TABLE_COUNT];
} SDataBase;

typedef struct SDbs_S {
340
  char         cfgDir[MAX_FILE_NAME_LEN+1];
341
  char         host[MAX_HOSTNAME_SIZE];
342 343
  struct sockaddr_in serv_addr;

344
  uint16_t     port;
345 346
  char         user[MAX_USERNAME_SIZE];
  char         password[MAX_PASSWORD_SIZE];
347
  char         resultFile[MAX_FILE_NAME_LEN+1];
348 349 350
  bool         use_metric;
  bool         insert_only;
  bool         do_aggreFunc;
351
  bool         asyncMode;
352

353 354 355
  uint32_t     threadCount;
  uint32_t     threadCountByCreateTbl;
  uint32_t     dbCount;
356 357 358
  SDataBase    db[MAX_DB_COUNT];

  // statistics
359 360
  uint64_t     totalInsertRows;
  uint64_t     totalAffectedRows;
361

362 363
} SDbs;

364
typedef struct SpecifiedQueryInfo_S {
365 366 367
  uint64_t     queryInterval;  // 0: unlimit  > 0   loop/s
  uint64_t     concurrent;
  uint64_t     sqlCount;
368
  uint32_t     asyncMode; // 0: sync, 1: async
369 370
  uint64_t     subscribeInterval; // ms
  uint64_t     queryTimes;
371
  bool         subscribeRestart;
372
  int          subscribeKeepProgress;
373
  char         sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1];
374
  char         result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1];
375
  int          resubAfterConsume[MAX_QUERY_SQL_COUNT];
376
  TAOS_SUB*    tsub[MAX_QUERY_SQL_COUNT];
377
  uint64_t     totalQueried;
378
} SpecifiedQueryInfo;
379

380
typedef struct SuperQueryInfo_S {
381
  char         sTblName[MAX_TB_NAME_SIZE+1];
382 383
  uint64_t     queryInterval;  // 0: unlimit  > 0   loop/s
  uint32_t     threadCnt;
384
  uint32_t     asyncMode; // 0: sync, 1: async
385
  uint64_t     subscribeInterval; // ms
386
  bool         subscribeRestart;
387
  int          subscribeKeepProgress;
388
  uint64_t     queryTimes;
389
  int64_t      childTblCount;
390
  char         childTblPrefix[MAX_TB_NAME_SIZE];
391
  uint64_t     sqlCount;
392
  char         sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1];
393
  char         result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1];
394
  int          resubAfterConsume;
395
  TAOS_SUB*    tsub[MAX_QUERY_SQL_COUNT];
396

397
  char*        childTblName;
398
  uint64_t     totalQueried;
399
} SuperQueryInfo;
400 401

typedef struct SQueryMetaInfo_S {
402
  char         cfgDir[MAX_FILE_NAME_LEN+1];
403
  char         host[MAX_HOSTNAME_SIZE];
404
  uint16_t     port;
405
  struct       sockaddr_in serv_addr;
406 407
  char         user[MAX_USERNAME_SIZE];
  char         password[MAX_PASSWORD_SIZE];
408
  char         dbName[MAX_DB_NAME_SIZE+1];
409
  char         queryMode[MAX_TB_NAME_SIZE];  // taosc, rest
410

411
  SpecifiedQueryInfo  specifiedQueryInfo;
412
  SuperQueryInfo      superQueryInfo;
413
  uint64_t     totalQueried;
414 415 416
} SQueryMetaInfo;

typedef struct SThreadInfo_S {
417 418 419 420 421 422 423 424
  TAOS *    taos;
  int       threadID;
  char      db_name[MAX_DB_NAME_SIZE+1];
  uint32_t  time_precision;
  char      fp[4096];
  char      tb_prefix[MAX_TB_NAME_SIZE];
  uint64_t  start_table_from;
  uint64_t  end_table_to;
425
  int64_t   ntables;
426 427 428 429
  uint64_t  data_of_rate;
  int64_t   start_time;
  char*     cols;
  bool      use_metric;
430 431 432
  SSuperTable* superTblInfo;

  // for async insert
433 434
  tsem_t    lock_sem;
  int64_t   counter;
435 436
  uint64_t  st;
  uint64_t  et;
437
  uint64_t  lastTs;
438

439
  // sample data
440
  int64_t   samplePos;
441
  // statistics
442 443
  uint64_t  totalInsertRows;
  uint64_t  totalAffectedRows;
444 445

  // insert delay statistics
446 447 448 449 450
  uint64_t  cntDelay;
  uint64_t  totalDelay;
  uint64_t  avgDelay;
  uint64_t  maxDelay;
  uint64_t  minDelay;
451

452
  // seq of query or subscribe
453
  uint64_t  querySeq;   // sequence number of sql command
454

455 456
} threadInfo;

457
#ifdef WINDOWS
458 459
#define _CRT_RAND_S

460
#include <windows.h>
461 462 463 464 465
#include <winsock2.h>

typedef unsigned __int32 uint32_t;

#pragma comment ( lib, "ws2_32.lib" )
466 467
// Some old MinGW/CYGWIN distributions don't define this:
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
468 469
  #define ENABLE_VIRTUAL_TERMINAL_PROCESSING  0x0004
#endif // ENABLE_VIRTUAL_TERMINAL_PROCESSING
470 471 472 473

static HANDLE g_stdoutHandle;
static DWORD g_consoleMode;

474
static void setupForAnsiEscape(void) {
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
  DWORD mode = 0;
  g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);

  if(g_stdoutHandle == INVALID_HANDLE_VALUE) {
    exit(GetLastError());
  }

  if(!GetConsoleMode(g_stdoutHandle, &mode)) {
    exit(GetLastError());
  }

  g_consoleMode = mode;

  // Enable ANSI escape codes
  mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;

  if(!SetConsoleMode(g_stdoutHandle, mode)) {
    exit(GetLastError());
493
  }
494 495
}

496
static void resetAfterAnsiEscape(void) {
497
  // Reset colors
498
  printf("\x1b[0m");
499 500 501 502 503 504

  // Reset console mode
  if(!SetConsoleMode(g_stdoutHandle, g_consoleMode)) {
    exit(GetLastError());
  }
}
505

506
static int taosRandom()
507 508 509 510 511 512
{
    int number;
    rand_s(&number);

    return number;
}
513
#else   // Not windows
514
static void setupForAnsiEscape(void) {}
515

516
static void resetAfterAnsiEscape(void) {
517 518 519
  // Reset colors
  printf("\x1b[0m");
}
520

521 522
#include <time.h>

523
static int taosRandom()
524
{
525
  return rand();
526 527
}

528
#endif // ifdef Windows
529

530
static void prompt();
531
static int createDatabasesAndStables();
532
static void createChildTables();
533
static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet);
534 535
static int postProceSql(char *host, struct sockaddr_in *pServAddr,
        uint16_t port, char* sqlstr, char *resultFile);
536 537 538 539 540 541 542

/* ************ Global variables ************  */

int32_t  randint[MAX_PREPARED_RAND];
int64_t  randbigint[MAX_PREPARED_RAND];
float    randfloat[MAX_PREPARED_RAND];
double   randdouble[MAX_PREPARED_RAND];
543
char *aggreFunc[] = {"*", "count(*)", "avg(col0)", "sum(col0)",
544 545
    "max(col0)", "min(col0)", "first(col0)", "last(col0)"};

546
SArguments g_args = {
547 548
                     NULL,            // metaFile
                     0,               // test_mode
549 550 551
                     "127.0.0.1",     // host
                     6030,            // port
                     "root",          // user
552
                     #ifdef _TD_POWER_
553 554 555 556 557 558 559 560
                     "powerdb",      // password
                     #else
                     "taosdata",      // password
                     #endif
                     "test",          // database
                     1,               // replica
                     "t",             // tb_prefix
                     NULL,            // sqlFile
561
                     true,            // use_metric
562
                     true,            // drop_database
563
                     true,            // insert_only
564
                     false,           // debug_print
565
                     false,           // verbose_print
566
                     false,           // performance statistic print
567 568 569 570
                     false,           // answer_yes;
                     "./output.txt",  // output_file
                     0,               // mode : sync or async
                     {
571 572 573 574
                     "INT",           // datatype
                     "INT",           // datatype
                     "INT",           // datatype
                     "INT",           // datatype
575 576
                     },
                     16,              // len_of_binary
577
                     4,               // num_of_CPR
578 579
                     10,              // num_of_connections/thread
                     0,               // insert_interval
580
                     1,               // query_times
581
                     0,               // interlace_rows;
582
                     30000,           // num_of_RPR
583
                     (1024*1024),         // max_sql_len
584 585 586 587 588 589 590 591 592 593 594 595
                     10000,           // num_of_tables
                     10000,           // num_of_DPT
                     0,               // abort
                     0,               // disorderRatio
                     1000,            // disorderRange
                     1,               // method_of_delete
                     NULL             // arg_list
};



static SDbs            g_Dbs;
596
static int64_t         g_totalChildTables = 0;
597 598 599 600
static SQueryMetaInfo  g_queryInfo;
static FILE *          g_fpOfInsertResult = NULL;

#define debugPrint(fmt, ...) \
601
    do { if (g_args.debug_print || g_args.verbose_print) \
602
      fprintf(stderr, "DEBG: "fmt, __VA_ARGS__); } while(0)
603

604
#define verbosePrint(fmt, ...) \
605 606
    do { if (g_args.verbose_print) \
        fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0)
607

608 609 610 611
#define performancePrint(fmt, ...) \
    do { if (g_args.performance_print) \
        fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0)

612 613 614 615
#define errorPrint(fmt, ...) \
    do { fprintf(stderr, "ERROR: "fmt, __VA_ARGS__); } while(0)


616
///////////////////////////////////////////////////
H
hzcheng 已提交
617

618 619
static void ERROR_EXIT(const char *msg) { perror(msg); exit(-1); }

620 621 622 623 624 625 626 627
#ifndef TAOSDEMO_COMMIT_SHA1
#define TAOSDEMO_COMMIT_SHA1 "unknown"
#endif

#ifndef TD_VERNUMBER
#define TD_VERNUMBER    "unknown"
#endif

628
#ifndef TAOSDEMO_STATUS
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
#define TAOSDEMO_STATUS "unknown"
#endif

static void printVersion() {
    char tdengine_ver[] = TD_VERNUMBER;
    char taosdemo_ver[] = TAOSDEMO_COMMIT_SHA1;
    char taosdemo_status[] = TAOSDEMO_STATUS;

    if (strlen(taosdemo_status) == 0) {
        printf("taosdemo verison %s-%s\n",
                tdengine_ver, taosdemo_ver);
    } else {
        printf("taosdemo verison %s-%s, status:%s\n",
                tdengine_ver, taosdemo_ver, taosdemo_status);
    }
}

646
static void printHelp() {
647
  char indent[10] = "        ";
648
  printf("%s%s%s%s\n", indent, "-f", indent,
649
          "The meta file to the execution procedure. Default is './meta.json'.");
650
  printf("%s%s%s%s\n", indent, "-u", indent,
651 652
          "The TDengine user name to use when connecting to the server. Default is 'root'.");
#ifdef _TD_POWER_
653
  printf("%s%s%s%s\n", indent, "-P", indent,
654
          "The password to use when connecting to the server. Default is 'powerdb'.");
655
  printf("%s%s%s%s\n", indent, "-c", indent,
656 657
          "Configuration directory. Default is '/etc/power/'.");
#else
658
  printf("%s%s%s%s\n", indent, "-P", indent,
659
          "The password to use when connecting to the server. Default is 'taosdata'.");
660
  printf("%s%s%s%s\n", indent, "-c", indent,
661
          "Configuration directory. Default is '/etc/taos/'.");
662
#endif
663
  printf("%s%s%s%s\n", indent, "-h", indent,
664
          "The host to connect to TDengine. Default is localhost.");
665
  printf("%s%s%s%s\n", indent, "-p", indent,
666
          "The TCP/IP port number to use for the connection. Default is 0.");
667
  printf("%s%s%s%s\n", indent, "-d", indent,
668
          "Destination database. Default is 'test'.");
669
  printf("%s%s%s%s\n", indent, "-a", indent,
670
          "Set the replica parameters of the database, Default 1, min: 1, max: 3.");
671
  printf("%s%s%s%s\n", indent, "-m", indent,
672 673
          "Table prefix name. Default is 't'.");
  printf("%s%s%s%s\n", indent, "-s", indent, "The select sql file.");
674
  printf("%s%s%s%s\n", indent, "-N", indent, "Use normal table flag.");
675
  printf("%s%s%s%s\n", indent, "-o", indent,
676
          "Direct output to the named file. Default is './output.txt'.");
677
  printf("%s%s%s%s\n", indent, "-q", indent,
678
          "Query mode -- 0: SYNC, 1: ASYNC. Default is SYNC.");
679
  printf("%s%s%s%s\n", indent, "-b", indent,
680
          "The data_type of columns, default: INT,INT,INT,INT.");
681
  printf("%s%s%s%s\n", indent, "-w", indent,
682
          "The length of data_type 'BINARY' or 'NCHAR'. Default is 16");
683 684 685
  printf("%s%s%s%s%d\n", indent, "-l", indent,
          "The number of columns per record. Default is 4. Max values is ",
       MAX_NUM_DATATYPE);
686
  printf("%s%s%s%s\n", indent, "-T", indent,
687
          "The number of threads. Default is 10.");
688
  printf("%s%s%s%s\n", indent, "-i", indent,
689
          "The sleep time (ms) between insertion. Default is 0.");
690
  printf("%s%s%s%s\n", indent, "-r", indent,
691
          "The number of records per request. Default is 30000.");
692
  printf("%s%s%s%s\n", indent, "-t", indent,
693
          "The number of tables. Default is 10000.");
694
  printf("%s%s%s%s\n", indent, "-n", indent,
695 696 697
          "The number of records per table. Default is 10000.");
  printf("%s%s%s%s\n", indent, "-x", indent, "Not insert only flag.");
  printf("%s%s%s%s\n", indent, "-y", indent, "Default input yes for prompt.");
698
  printf("%s%s%s%s\n", indent, "-O", indent,
699
          "Insert mode--0: In order, 1 ~ 50: disorder ratio. Default is in order.");
700
  printf("%s%s%s%s\n", indent, "-R", indent,
701
          "Out of order data's range, ms, default is 1000.");
702
  printf("%s%s%s%s\n", indent, "-g", indent,
703
          "Print debug info.");
704
  printf("%s%s%s\n", indent, "-V, --version\t",
705
          "Print version info.");
706 707
  printf("%s%s%s%s\n", indent, "--help\t", indent,
          "Print command line arguments list info.");
708
/*    printf("%s%s%s%s\n", indent, "-D", indent,
709 710 711 712
          "if elete database if exists. 0: no, 1: yes, default is 1");
          */
}

713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
static bool isStringNumber(char *input)
{
  int len = strlen(input);
  if (0 == len) {
    return false;
  }

  for (int i = 0; i < len; i++) {
    if (!isdigit(input[i]))
      return false;
  }

  return true;
}

728
static void parse_args(int argc, char *argv[], SArguments *arguments) {
729 730 731 732 733

  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "-f") == 0) {
      arguments->metaFile = argv[++i];
    } else if (strcmp(argv[i], "-c") == 0) {
734 735 736 737 738
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-c need a valid path following!\n");
        exit(EXIT_FAILURE);
      }
739
      tstrncpy(configDir, argv[++i], TSDB_FILENAME_LEN);
740
    } else if (strcmp(argv[i], "-h") == 0) {
741 742 743 744 745
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-h need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
746 747
      arguments->host = argv[++i];
    } else if (strcmp(argv[i], "-p") == 0) {
748 749 750 751 752 753
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-p need a number following!\n");
        exit(EXIT_FAILURE);
      }
754 755
      arguments->port = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-u") == 0) {
756 757 758 759 760
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-u need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
761 762
      arguments->user = argv[++i];
    } else if (strcmp(argv[i], "-P") == 0) {
763 764 765 766 767
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-P need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
768 769
      arguments->password = argv[++i];
    } else if (strcmp(argv[i], "-o") == 0) {
770 771 772 773 774
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-o need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
775 776
      arguments->output_file = argv[++i];
    } else if (strcmp(argv[i], "-s") == 0) {
777 778 779 780 781
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-s need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
782 783
      arguments->sqlFile = argv[++i];
    } else if (strcmp(argv[i], "-q") == 0) {
784 785
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
786
        printHelp();
787
        errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, 1: ASYNC. Default is SYNC.\n");
788 789
        exit(EXIT_FAILURE);
      }
790
      arguments->async_mode = atoi(argv[++i]);
791
    } else if (strcmp(argv[i], "-T") == 0) {
792 793
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
794 795 796 797
        printHelp();
        errorPrint("%s", "\n\t-T need a number following!\n");
        exit(EXIT_FAILURE);
      }
798 799
      arguments->num_of_threads = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-i") == 0) {
800 801
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
802 803 804 805
        printHelp();
        errorPrint("%s", "\n\t-i need a number following!\n");
        exit(EXIT_FAILURE);
      }
806
      arguments->insert_interval = atoi(argv[++i]);
807
    } else if (strcmp(argv[i], "-qt") == 0) {
808 809
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
810
        printHelp();
811
        errorPrint("%s", "\n\t-qt need a number following!\n");
812 813
        exit(EXIT_FAILURE);
      }
814
      arguments->query_times = atoi(argv[++i]);
815
    } else if (strcmp(argv[i], "-B") == 0) {
816 817
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
818 819 820 821
        printHelp();
        errorPrint("%s", "\n\t-B need a number following!\n");
        exit(EXIT_FAILURE);
      }
822
      arguments->interlace_rows = atoi(argv[++i]);
823
    } else if (strcmp(argv[i], "-r") == 0) {
824 825
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
826 827 828 829
        printHelp();
        errorPrint("%s", "\n\t-r need a number following!\n");
        exit(EXIT_FAILURE);
      }
830 831
      arguments->num_of_RPR = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-t") == 0) {
832 833 834 835 836 837
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-t need a number following!\n");
        exit(EXIT_FAILURE);
      }
838 839
      arguments->num_of_tables = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-n") == 0) {
840 841 842 843 844 845
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-n need a number following!\n");
        exit(EXIT_FAILURE);
      }
846 847
      arguments->num_of_DPT = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-d") == 0) {
848 849 850 851 852
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-d need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
853 854
      arguments->database = argv[++i];
    } else if (strcmp(argv[i], "-l") == 0) {
855 856 857 858 859 860
      if (argc == i+1) {
        if (!isStringNumber(argv[i+1])) {
            printHelp();
            errorPrint("%s", "\n\t-l need a number following!\n");
            exit(EXIT_FAILURE);
        }
861
      }
862
      arguments->num_of_CPR = atoi(argv[++i]);
863 864 865 866 867 868 869 870 871 872 873

      if (arguments->num_of_CPR > MAX_NUM_DATATYPE) {
          printf("WARNING: max acceptible columns count is %d\n", MAX_NUM_DATATYPE);
          prompt();
          arguments->num_of_CPR = MAX_NUM_DATATYPE;
      }

      for (int col = arguments->num_of_CPR; col < MAX_NUM_DATATYPE; col++) {
          arguments->datatype[col] = NULL;
      }

874
    } else if (strcmp(argv[i], "-b") == 0) {
875 876 877 878 879
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-b need valid string following!\n");
        exit(EXIT_FAILURE);
      }
880 881
      ++i;
      if (strstr(argv[i], ",") == NULL) {
882
        // only one col
883 884 885 886 887 888 889
        if (strcasecmp(argv[i], "INT")
                && strcasecmp(argv[i], "FLOAT")
                && strcasecmp(argv[i], "TINYINT")
                && strcasecmp(argv[i], "BOOL")
                && strcasecmp(argv[i], "SMALLINT")
                && strcasecmp(argv[i], "BIGINT")
                && strcasecmp(argv[i], "DOUBLE")
890
                && strcasecmp(argv[i], "BINARY")
891 892
                && strcasecmp(argv[i], "NCHAR")) {
          printHelp();
893
          errorPrint("%s", "-b: Invalid data_type!\n");
894
          exit(EXIT_FAILURE);
895
        }
896
        arguments->datatype[0] = argv[i];
897
      } else {
898
        // more than one col
899
        int index = 0;
900 901
        g_dupstr = strdup(argv[i]);
        char *running = g_dupstr;
902
        char *token = strsep(&running, ",");
903
        while(token != NULL) {
904 905 906 907 908 909 910 911 912 913
          if (strcasecmp(token, "INT")
                  && strcasecmp(token, "FLOAT")
                  && strcasecmp(token, "TINYINT")
                  && strcasecmp(token, "BOOL")
                  && strcasecmp(token, "SMALLINT")
                  && strcasecmp(token, "BIGINT")
                  && strcasecmp(token, "DOUBLE")
                  && strcasecmp(token, "BINARY")
                  && strcasecmp(token, "NCHAR")) {
            printHelp();
914
            free(g_dupstr);
915
            errorPrint("%s", "-b: Invalid data_type!\n");
916
            exit(EXIT_FAILURE);
H
hzcheng 已提交
917
          }
918
          arguments->datatype[index++] = token;
919 920
          token = strsep(&running, ",");
          if (index >= MAX_NUM_DATATYPE) break;
S
TD-1057  
Shengliang Guan 已提交
921
        }
922
        arguments->datatype[index] = NULL;
923
      }
924
    } else if (strcmp(argv[i], "-w") == 0) {
925 926 927 928 929 930
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-w need a number following!\n");
        exit(EXIT_FAILURE);
      }
931 932
      arguments->len_of_binary = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-m") == 0) {
933 934 935 936 937 938
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-m need a number following!\n");
        exit(EXIT_FAILURE);
      }
939
      arguments->tb_prefix = argv[++i];
940 941
    } else if (strcmp(argv[i], "-N") == 0) {
      arguments->use_metric = false;
942
    } else if (strcmp(argv[i], "-x") == 0) {
943
      arguments->insert_only = false;
944
    } else if (strcmp(argv[i], "-y") == 0) {
945
      arguments->answer_yes = true;
946 947
    } else if (strcmp(argv[i], "-g") == 0) {
      arguments->debug_print = true;
948 949
    } else if (strcmp(argv[i], "-gg") == 0) {
      arguments->verbose_print = true;
950 951
    } else if (strcmp(argv[i], "-pp") == 0) {
      arguments->performance_print = true;
952
    } else if (strcmp(argv[i], "-O") == 0) {
953 954 955 956 957 958
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-O need a number following!\n");
        exit(EXIT_FAILURE);
      }
959

960
      arguments->disorderRatio = atoi(argv[++i]);
961

962
      if (arguments->disorderRatio > 50) {
963
        arguments->disorderRatio = 50;
964
      }
965

966
      if (arguments->disorderRatio < 0) {
967
        arguments->disorderRatio = 0;
968
      }
969

970
    } else if (strcmp(argv[i], "-R") == 0) {
971 972 973 974 975 976
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-R need a number following!\n");
        exit(EXIT_FAILURE);
      }
977

978
      arguments->disorderRange = atoi(argv[++i]);
979 980 981
      if (arguments->disorderRange < 0)
        arguments->disorderRange = 1000;

982
    } else if (strcmp(argv[i], "-a") == 0) {
983 984 985 986 987 988
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-a need a number following!\n");
        exit(EXIT_FAILURE);
      }
989 990 991
      arguments->replica = atoi(argv[++i]);
      if (arguments->replica > 3 || arguments->replica < 1) {
          arguments->replica = 1;
992
      }
993 994
    } else if (strcmp(argv[i], "-D") == 0) {
      arguments->method_of_delete = atoi(argv[++i]);
995 996 997
      if (arguments->method_of_delete > 3) {
        errorPrint("%s", "\n\t-D need a valud (0~3) number following!\n");
        exit(EXIT_FAILURE);
S
TD-1057  
Shengliang Guan 已提交
998
      }
999 1000 1001 1002
    } else if ((strcmp(argv[i], "--version") == 0) ||
        (strcmp(argv[i], "-V") == 0)){
      printVersion();
      exit(0);
1003 1004 1005 1006 1007
    } else if (strcmp(argv[i], "--help") == 0) {
      printHelp();
      exit(0);
    } else {
      printHelp();
1008
      errorPrint("%s", "ERROR: wrong options\n");
1009
      exit(EXIT_FAILURE);
S
TD-1057  
Shengliang Guan 已提交
1010 1011
    }
  }
1012

1013 1014
  if (((arguments->debug_print) && (arguments->metaFile == NULL))
          || arguments->verbose_print) {
1015
    printf("###################################################################\n");
1016
    printf("# meta file:                         %s\n", arguments->metaFile);
1017
    printf("# Server IP:                         %s:%hu\n",
1018 1019 1020 1021 1022
            arguments->host == NULL ? "localhost" : arguments->host,
            arguments->port );
    printf("# User:                              %s\n", arguments->user);
    printf("# Password:                          %s\n", arguments->password);
    printf("# Use metric:                        %s\n", arguments->use_metric ? "true" : "false");
1023 1024 1025 1026 1027 1028 1029 1030 1031
    if (*(arguments->datatype)) {
        printf("# Specified data type:               ");
        for (int i = 0; i < MAX_NUM_DATATYPE; i++)
            if (arguments->datatype[i])
               printf("%s,", arguments->datatype[i]);
            else
                break;
        printf("\n");
    }
1032
    printf("# Insertion interval:                %"PRIu64"\n",
1033
            arguments->insert_interval);
1034
    printf("# Number of records per req:         %"PRIu64"\n",
1035
            arguments->num_of_RPR);
1036
    printf("# Max SQL length:                    %"PRIu64"\n",
1037
            arguments->max_sql_len);
1038
    printf("# Length of Binary:                  %d\n", arguments->len_of_binary);
1039
    printf("# Number of Threads:                 %d\n", arguments->num_of_threads);
1040
    printf("# Number of Tables:                  %"PRId64"\n",
1041
            arguments->num_of_tables);
1042
    printf("# Number of Data per Table:          %"PRId64"\n",
1043
            arguments->num_of_DPT);
1044 1045 1046 1047 1048
    printf("# Database name:                     %s\n", arguments->database);
    printf("# Table prefix:                      %s\n", arguments->tb_prefix);
    if (arguments->disorderRatio) {
      printf("# Data order:                        %d\n", arguments->disorderRatio);
      printf("# Data out of order rate:            %d\n", arguments->disorderRange);
1049

1050 1051 1052 1053
    }
    printf("# Delete method:                     %d\n", arguments->method_of_delete);
    printf("# Answer yes when prompt:            %d\n", arguments->answer_yes);
    printf("# Print debug info:                  %d\n", arguments->debug_print);
1054
    printf("# Print verbose info:                %d\n", arguments->verbose_print);
1055
    printf("###################################################################\n");
1056 1057

    prompt();
1058
  }
1059
}
H
hzcheng 已提交
1060

1061 1062 1063 1064
static bool getInfoFromJsonFile(char* file);
//static int generateOneRowDataForStb(SSuperTable* stbInfo);
//static int getDataIntoMemForStb(SSuperTable* stbInfo);
static void init_rand_data();
1065
static void tmfclose(FILE *fp) {
1066 1067 1068 1069
  if (NULL != fp) {
    fclose(fp);
  }
}
1070

1071
static void tmfree(char *buf) {
1072 1073
  if (NULL != buf) {
    free(buf);
H
Hui Li 已提交
1074
  }
1075
}
H
Hui Li 已提交
1076

1077
static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet) {
1078 1079 1080
  int i;
  TAOS_RES *res = NULL;
  int32_t   code = -1;
1081

1082 1083 1084 1085
  for (i = 0; i < 5; i++) {
    if (NULL != res) {
      taos_free_result(res);
      res = NULL;
H
hzcheng 已提交
1086
    }
1087

1088 1089 1090 1091
    res = taos_query(taos, command);
    code = taos_errno(res);
    if (0 == code) {
      break;
1092
    }
H
hzcheng 已提交
1093 1094
  }

1095
  if (code != 0) {
1096 1097
    if (!quiet) {
      debugPrint("%s() LN%d - command: %s\n", __func__, __LINE__, command);
1098
      errorPrint("Failed to execute %s, reason: %s\n", command, taos_errstr(res));
1099
    }
1100 1101 1102
    taos_free_result(res);
    //taos_close(taos);
    return -1;
1103
  }
H
hzcheng 已提交
1104

1105 1106 1107 1108
  if (INSERT_TYPE == type) {
    int affectedRows = taos_affected_rows(res);
    taos_free_result(res);
    return affectedRows;
H
hzcheng 已提交
1109
  }
1110

1111
  taos_free_result(res);
1112 1113
  return 0;
}
H
hzcheng 已提交
1114

1115 1116
static void appendResultBufToFile(char *resultBuf, char *resultFile)
{
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
    FILE *fp = NULL;
    if (resultFile[0] != 0) {
        fp = fopen(resultFile, "at");
        if (fp == NULL) {
            errorPrint(
                    "%s() LN%d, failed to open result file: %s, result will not save to file\n",
                    __func__, __LINE__, resultFile);
            return;
        }
        fprintf(fp, "%s", resultBuf);
        tmfclose(fp);
1128
    }
1129 1130
}

1131

1132 1133 1134 1135 1136 1137
static void appendResultToFile(TAOS_RES *res, char* resultFile) {
  TAOS_ROW    row = NULL;
  int         num_rows = 0;
  int         num_fields = taos_field_count(res);
  TAOS_FIELD *fields     = taos_fetch_fields(res);

1138 1139
  char* databuf = (char*) calloc(1, 100*1024*1024);
  if (databuf == NULL) {
1140 1141
    errorPrint("%s() LN%d, failed to malloc, warning: save result to file slowly!\n",
            __func__, __LINE__);
1142 1143
    return ;
  }
H
hzcheng 已提交
1144

1145 1146
  int   totalLen = 0;
  char  temp[16000];
H
hzcheng 已提交
1147

1148
  // fetch the records row by row
1149
  while((row = taos_fetch_row(res))) {
1150
    if (totalLen >= 100*1024*1024 - 32000) {
1151
      appendResultBufToFile(databuf, resultFile);
1152 1153
      totalLen = 0;
      memset(databuf, 0, 100*1024*1024);
H
hzcheng 已提交
1154
    }
1155 1156 1157 1158 1159 1160
    num_rows++;
    int len = taos_print_row(temp, row, fields, num_fields);
    len += sprintf(temp + len, "\n");
    //printf("query result:%s\n", temp);
    memcpy(databuf + totalLen, temp, len);
    totalLen += len;
H
hzcheng 已提交
1161 1162
  }

1163 1164
  verbosePrint("%s() LN%d, databuf=%s resultFile=%s\n",
          __func__, __LINE__, databuf, resultFile);
1165
  appendResultBufToFile(databuf, resultFile);
1166 1167
  free(databuf);
}
H
hzcheng 已提交
1168

1169
static void selectAndGetResult(
1170
        threadInfo *pThreadInfo, char *command)
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
{
  if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", strlen("taosc"))) {
    TAOS_RES *res = taos_query(pThreadInfo->taos, command);
    if (res == NULL || taos_errno(res) != 0) {
        errorPrint("%s() LN%d, failed to execute sql:%s, reason:%s\n",
            __func__, __LINE__, command, taos_errstr(res));
        taos_free_result(res);
        return;
    }

1181 1182
    if ((strlen(pThreadInfo->fp))) {
      appendResultToFile(res, pThreadInfo->fp);
1183
    }
1184
    taos_free_result(res);
1185

1186 1187 1188 1189
  } else if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) {
      int retCode = postProceSql(
              g_queryInfo.host, &(g_queryInfo.serv_addr), g_queryInfo.port,
              command,
1190
              pThreadInfo->fp);
1191 1192 1193 1194 1195 1196 1197 1198
      if (0 != retCode) {
        printf("====restful return fail, threadID[%d]\n", pThreadInfo->threadID);
      }

  } else {
      errorPrint("%s() LN%d, unknown query mode: %s\n",
        __func__, __LINE__, g_queryInfo.queryMode);
  }
1199
}
H
hzcheng 已提交
1200

1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239
static int32_t rand_bool(){
  static int cursor;
  cursor++;
  cursor = cursor % MAX_PREPARED_RAND;
  return randint[cursor] % 2;
}

static int32_t rand_tinyint(){
  static int cursor;
  cursor++;
  cursor = cursor % MAX_PREPARED_RAND;
  return randint[cursor] % 128;
}

static int32_t rand_smallint(){
  static int cursor;
  cursor++;
  cursor = cursor % MAX_PREPARED_RAND;
  return randint[cursor] % 32767;
}

static int32_t rand_int(){
  static int cursor;
  cursor++;
  cursor = cursor % MAX_PREPARED_RAND;
  return randint[cursor];
}

static int64_t rand_bigint(){
  static int cursor;
  cursor++;
  cursor = cursor % MAX_PREPARED_RAND;
  return randbigint[cursor];
}

static float rand_float(){
  static int cursor;
  cursor++;
  cursor = cursor % MAX_PREPARED_RAND;
1240
  return randfloat[cursor];
1241 1242
}

1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259
#if 0
static const char charNum[] = "0123456789";

static void nonrand_string(char *, int) __attribute__ ((unused));   // reserve for debugging purpose
static void nonrand_string(char *str, int size)
{
  str[0] = 0;
  if (size > 0) {
    int n;
    for (n = 0; n < size; n++) {
      str[n] = charNum[n % 10];
    }
    str[n] = 0;
  }
}
#endif

1260
static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
1261

1262
static void rand_string(char *str, int size) {
1263 1264 1265 1266
  str[0] = 0;
  if (size > 0) {
    //--size;
    int n;
1267
    for (n = 0; n < size; n++) {
1268
      int key = abs(rand_tinyint()) % (int)(sizeof(charset) - 1);
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
      str[n] = charset[key];
    }
    str[n] = 0;
  }
}

static double rand_double() {
  static int cursor;
  cursor++;
  cursor = cursor % MAX_PREPARED_RAND;
  return randdouble[cursor];

}

static void init_rand_data() {
  for (int i = 0; i < MAX_PREPARED_RAND; i++){
1285 1286 1287 1288
    randint[i] = (int)(taosRandom() % 65535);
    randbigint[i] = (int64_t)(taosRandom() % 2147483648);
    randfloat[i] = (float)(taosRandom() / 1000.0);
    randdouble[i] = (double)(taosRandom() / 1000000.0);
1289 1290 1291
  }
}

1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311
#define SHOW_PARSE_RESULT_START()   \
    do { if (g_args.metaFile)  \
        printf("\033[1m\033[40;32m================ %s parse result START ================\033[0m\n", \
                g_args.metaFile); } while(0)

#define SHOW_PARSE_RESULT_END() \
    do { if (g_args.metaFile)   \
        printf("\033[1m\033[40;32m================ %s parse result END================\033[0m\n", \
                g_args.metaFile); } while(0)

#define SHOW_PARSE_RESULT_START_TO_FILE(fp)   \
    do { if (g_args.metaFile)  \
        fprintf(fp, "\033[1m\033[40;32m================ %s parse result START ================\033[0m\n", \
                g_args.metaFile); } while(0)

#define SHOW_PARSE_RESULT_END_TO_FILE(fp) \
    do { if (g_args.metaFile)   \
        fprintf(fp, "\033[1m\033[40;32m================ %s parse result END================\033[0m\n", \
                g_args.metaFile); } while(0)

1312
static int printfInsertMeta() {
1313 1314
    SHOW_PARSE_RESULT_START();

1315 1316
  printf("host:                       \033[33m%s:%u\033[0m\n",
          g_Dbs.host, g_Dbs.port);
1317 1318
  printf("user:                       \033[33m%s\033[0m\n", g_Dbs.user);
  printf("password:                   \033[33m%s\033[0m\n", g_Dbs.password);
1319
  printf("configDir:                  \033[33m%s\033[0m\n", configDir);
1320 1321
  printf("resultFile:                 \033[33m%s\033[0m\n", g_Dbs.resultFile);
  printf("thread num of insert data:  \033[33m%d\033[0m\n", g_Dbs.threadCount);
1322 1323
  printf("thread num of create table: \033[33m%d\033[0m\n",
          g_Dbs.threadCountByCreateTbl);
1324
  printf("top insert interval:        \033[33m%"PRIu64"\033[0m\n",
1325
          g_args.insert_interval);
1326
  printf("number of records per req:  \033[33m%"PRIu64"\033[0m\n",
1327
          g_args.num_of_RPR);
1328
  printf("max sql length:             \033[33m%"PRIu64"\033[0m\n",
1329
          g_args.max_sql_len);
1330 1331

  printf("database count:             \033[33m%d\033[0m\n", g_Dbs.dbCount);
1332

1333 1334
  for (int i = 0; i < g_Dbs.dbCount; i++) {
    printf("database[\033[33m%d\033[0m]:\n", i);
1335 1336
    printf("  database[%d] name:      \033[33m%s\033[0m\n",
            i, g_Dbs.db[i].dbName);
1337
    if (0 == g_Dbs.db[i].drop) {
1338 1339 1340
      printf("  drop:                  \033[33mno\033[0m\n");
    } else {
      printf("  drop:                  \033[33myes\033[0m\n");
1341 1342 1343
    }

    if (g_Dbs.db[i].dbCfg.blocks > 0) {
1344 1345
      printf("  blocks:                \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.blocks);
1346 1347
    }
    if (g_Dbs.db[i].dbCfg.cache > 0) {
1348 1349
      printf("  cache:                 \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.cache);
1350 1351
    }
    if (g_Dbs.db[i].dbCfg.days > 0) {
1352 1353
      printf("  days:                  \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.days);
1354 1355
    }
    if (g_Dbs.db[i].dbCfg.keep > 0) {
1356 1357
      printf("  keep:                  \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.keep);
1358 1359
    }
    if (g_Dbs.db[i].dbCfg.replica > 0) {
1360 1361
      printf("  replica:               \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.replica);
1362 1363
    }
    if (g_Dbs.db[i].dbCfg.update > 0) {
1364 1365
      printf("  update:                \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.update);
1366 1367
    }
    if (g_Dbs.db[i].dbCfg.minRows > 0) {
1368 1369
      printf("  minRows:               \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.minRows);
1370 1371
    }
    if (g_Dbs.db[i].dbCfg.maxRows > 0) {
1372 1373
      printf("  maxRows:               \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.maxRows);
1374 1375 1376 1377 1378
    }
    if (g_Dbs.db[i].dbCfg.comp > 0) {
      printf("  comp:                  \033[33m%d\033[0m\n", g_Dbs.db[i].dbCfg.comp);
    }
    if (g_Dbs.db[i].dbCfg.walLevel > 0) {
1379 1380
      printf("  walLevel:              \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.walLevel);
1381 1382
    }
    if (g_Dbs.db[i].dbCfg.fsync > 0) {
1383 1384
      printf("  fsync:                 \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.fsync);
1385 1386
    }
    if (g_Dbs.db[i].dbCfg.quorum > 0) {
1387 1388
      printf("  quorum:                \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.quorum);
1389 1390
    }
    if (g_Dbs.db[i].dbCfg.precision[0] != 0) {
1391 1392
      if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
              || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) {
1393 1394
        printf("  precision:             \033[33m%s\033[0m\n",
            g_Dbs.db[i].dbCfg.precision);
1395
      } else {
1396 1397 1398
        printf("\033[1m\033[40;31m  precision error:       %s\033[0m\n",
                g_Dbs.db[i].dbCfg.precision);
        return -1;
1399 1400 1401
      }
    }

1402
    printf("  super table count:     \033[33m%"PRIu64"\033[0m\n",
1403
        g_Dbs.db[i].superTblCount);
1404 1405
    for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) {
      printf("  super table[\033[33m%"PRIu64"\033[0m]:\n", j);
1406

1407 1408
      printf("      stbName:           \033[33m%s\033[0m\n",
          g_Dbs.db[i].superTbls[j].sTblName);
1409 1410 1411 1412 1413 1414 1415 1416

      if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) {
        printf("      autoCreateTable:   \033[33m%s\033[0m\n",  "no");
      } else if (AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) {
        printf("      autoCreateTable:   \033[33m%s\033[0m\n",  "yes");
      } else {
        printf("      autoCreateTable:   \033[33m%s\033[0m\n",  "error");
      }
1417

1418 1419 1420 1421 1422 1423 1424
      if (TBL_NO_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) {
        printf("      childTblExists:    \033[33m%s\033[0m\n",  "no");
      } else if (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) {
        printf("      childTblExists:    \033[33m%s\033[0m\n",  "yes");
      } else {
        printf("      childTblExists:    \033[33m%s\033[0m\n",  "error");
      }
1425

1426
      printf("      childTblCount:     \033[33m%"PRId64"\033[0m\n",
1427 1428 1429 1430 1431 1432 1433
              g_Dbs.db[i].superTbls[j].childTblCount);
      printf("      childTblPrefix:    \033[33m%s\033[0m\n",
              g_Dbs.db[i].superTbls[j].childTblPrefix);
      printf("      dataSource:        \033[33m%s\033[0m\n",
              g_Dbs.db[i].superTbls[j].dataSource);
      printf("      insertMode:        \033[33m%s\033[0m\n",
              g_Dbs.db[i].superTbls[j].insertMode);
1434
      if (g_Dbs.db[i].superTbls[j].childTblLimit > 0) {
1435
        printf("      childTblLimit:     \033[33m%"PRId64"\033[0m\n",
1436
                g_Dbs.db[i].superTbls[j].childTblLimit);
1437
      }
1438
      if (g_Dbs.db[i].superTbls[j].childTblOffset > 0) {
1439
        printf("      childTblOffset:    \033[33m%"PRIu64"\033[0m\n",
1440
                g_Dbs.db[i].superTbls[j].childTblOffset);
1441
      }
1442
      printf("      insertRows:        \033[33m%"PRId64"\033[0m\n",
1443
              g_Dbs.db[i].superTbls[j].insertRows);
1444
/*
1445
      if (0 == g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl) {
1446
        printf("      multiThreadWriteOneTbl:  \033[33mno\033[0m\n");
1447
      }else {
1448
        printf("      multiThreadWriteOneTbl:  \033[33myes\033[0m\n");
1449
      }
1450
      */
1451
      printf("      interlaceRows:     \033[33m%"PRIu64"\033[0m\n",
1452
              g_Dbs.db[i].superTbls[j].interlaceRows);
1453 1454

      if (g_Dbs.db[i].superTbls[j].interlaceRows > 0) {
1455
        printf("      stable insert interval:   \033[33m%"PRIu64"\033[0m\n",
1456 1457 1458
            g_Dbs.db[i].superTbls[j].insertInterval);
      }

1459 1460 1461 1462
      printf("      disorderRange:     \033[33m%d\033[0m\n",
              g_Dbs.db[i].superTbls[j].disorderRange);
      printf("      disorderRatio:     \033[33m%d\033[0m\n",
              g_Dbs.db[i].superTbls[j].disorderRatio);
1463
      printf("      maxSqlLen:         \033[33m%"PRIu64"\033[0m\n",
1464
              g_Dbs.db[i].superTbls[j].maxSqlLen);
1465
      printf("      timeStampStep:     \033[33m%"PRId64"\033[0m\n",
1466 1467 1468 1469 1470 1471 1472 1473 1474
              g_Dbs.db[i].superTbls[j].timeStampStep);
      printf("      startTimestamp:    \033[33m%s\033[0m\n",
              g_Dbs.db[i].superTbls[j].startTimestamp);
      printf("      sampleFormat:      \033[33m%s\033[0m\n",
              g_Dbs.db[i].superTbls[j].sampleFormat);
      printf("      sampleFile:        \033[33m%s\033[0m\n",
              g_Dbs.db[i].superTbls[j].sampleFile);
      printf("      tagsFile:          \033[33m%s\033[0m\n",
              g_Dbs.db[i].superTbls[j].tagsFile);
1475
      printf("      columnCount:       \033[33m%d\033[0m\n",
1476
              g_Dbs.db[i].superTbls[j].columnCount);
1477 1478
      for (int k = 0; k < g_Dbs.db[i].superTbls[j].columnCount; k++) {
        //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].columns[k].dataType, g_Dbs.db[i].superTbls[j].columns[k].dataLen);
1479 1480 1481 1482
        if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType,
                       "binary", 6))
                || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType,
                       "nchar", 5))) {
1483
          printf("column[\033[33m%d\033[0m]:\033[33m%s(%d)\033[0m ", k,
1484 1485
                  g_Dbs.db[i].superTbls[j].columns[k].dataType,
                  g_Dbs.db[i].superTbls[j].columns[k].dataLen);
1486
        } else {
1487 1488
          printf("column[%d]:\033[33m%s\033[0m ", k,
                  g_Dbs.db[i].superTbls[j].columns[k].dataType);
1489 1490 1491
        }
      }
      printf("\n");
1492 1493 1494

      printf("      tagCount:            \033[33m%d\033[0m\n        ",
              g_Dbs.db[i].superTbls[j].tagCount);
1495 1496
      for (int k = 0; k < g_Dbs.db[i].superTbls[j].tagCount; k++) {
        //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].tags[k].dataType, g_Dbs.db[i].superTbls[j].tags[k].dataLen);
1497 1498 1499 1500
        if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
                        "binary", strlen("binary")))
                || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
                        "nchar", strlen("nchar")))) {
1501
          printf("tag[%d]:\033[33m%s(%d)\033[0m ", k,
1502 1503
                  g_Dbs.db[i].superTbls[j].tags[k].dataType,
                  g_Dbs.db[i].superTbls[j].tags[k].dataLen);
1504
        } else {
1505 1506
          printf("tag[%d]:\033[33m%s\033[0m ", k,
                  g_Dbs.db[i].superTbls[j].tags[k].dataType);
1507
        }
1508 1509 1510 1511 1512
      }
      printf("\n");
    }
    printf("\n");
  }
1513 1514

  SHOW_PARSE_RESULT_END();
1515 1516

  return 0;
1517 1518 1519
}

static void printfInsertMetaToFile(FILE* fp) {
1520 1521

  SHOW_PARSE_RESULT_START_TO_FILE(fp);
1522

1523 1524
  fprintf(fp, "host:                       %s:%u\n", g_Dbs.host, g_Dbs.port);
  fprintf(fp, "user:                       %s\n", g_Dbs.user);
1525
  fprintf(fp, "configDir:                  %s\n", configDir);
1526 1527 1528
  fprintf(fp, "resultFile:                 %s\n", g_Dbs.resultFile);
  fprintf(fp, "thread num of insert data:  %d\n", g_Dbs.threadCount);
  fprintf(fp, "thread num of create table: %d\n", g_Dbs.threadCountByCreateTbl);
1529 1530
  fprintf(fp, "number of records per req:  %"PRIu64"\n", g_args.num_of_RPR);
  fprintf(fp, "max sql length:             %"PRIu64"\n", g_args.max_sql_len);
1531
  fprintf(fp, "database count:          %d\n", g_Dbs.dbCount);
1532

1533 1534
  for (int i = 0; i < g_Dbs.dbCount; i++) {
    fprintf(fp, "database[%d]:\n", i);
1535
    fprintf(fp, "  database[%d] name:       %s\n", i, g_Dbs.db[i].dbName);
1536
    if (0 == g_Dbs.db[i].drop) {
1537
      fprintf(fp, "  drop:                  no\n");
1538
    }else {
1539
      fprintf(fp, "  drop:                  yes\n");
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578
    }

    if (g_Dbs.db[i].dbCfg.blocks > 0) {
      fprintf(fp, "  blocks:                %d\n", g_Dbs.db[i].dbCfg.blocks);
    }
    if (g_Dbs.db[i].dbCfg.cache > 0) {
      fprintf(fp, "  cache:                 %d\n", g_Dbs.db[i].dbCfg.cache);
    }
    if (g_Dbs.db[i].dbCfg.days > 0) {
      fprintf(fp, "  days:                  %d\n", g_Dbs.db[i].dbCfg.days);
    }
    if (g_Dbs.db[i].dbCfg.keep > 0) {
      fprintf(fp, "  keep:                  %d\n", g_Dbs.db[i].dbCfg.keep);
    }
    if (g_Dbs.db[i].dbCfg.replica > 0) {
      fprintf(fp, "  replica:               %d\n", g_Dbs.db[i].dbCfg.replica);
    }
    if (g_Dbs.db[i].dbCfg.update > 0) {
      fprintf(fp, "  update:                %d\n", g_Dbs.db[i].dbCfg.update);
    }
    if (g_Dbs.db[i].dbCfg.minRows > 0) {
      fprintf(fp, "  minRows:               %d\n", g_Dbs.db[i].dbCfg.minRows);
    }
    if (g_Dbs.db[i].dbCfg.maxRows > 0) {
      fprintf(fp, "  maxRows:               %d\n", g_Dbs.db[i].dbCfg.maxRows);
    }
    if (g_Dbs.db[i].dbCfg.comp > 0) {
      fprintf(fp, "  comp:                  %d\n", g_Dbs.db[i].dbCfg.comp);
    }
    if (g_Dbs.db[i].dbCfg.walLevel > 0) {
      fprintf(fp, "  walLevel:              %d\n", g_Dbs.db[i].dbCfg.walLevel);
    }
    if (g_Dbs.db[i].dbCfg.fsync > 0) {
      fprintf(fp, "  fsync:                 %d\n", g_Dbs.db[i].dbCfg.fsync);
    }
    if (g_Dbs.db[i].dbCfg.quorum > 0) {
      fprintf(fp, "  quorum:                %d\n", g_Dbs.db[i].dbCfg.quorum);
    }
    if (g_Dbs.db[i].dbCfg.precision[0] != 0) {
1579 1580
      if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
              || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) {
1581 1582
        fprintf(fp, "  precision:             %s\n",
                g_Dbs.db[i].dbCfg.precision);
1583
      } else {
1584 1585
        fprintf(fp, "  precision error:       %s\n",
                g_Dbs.db[i].dbCfg.precision);
1586 1587 1588
      }
    }

1589 1590
    fprintf(fp, "  super table count:     %"PRIu64"\n",
            g_Dbs.db[i].superTblCount);
1591 1592
    for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
      fprintf(fp, "  super table[%d]:\n", j);
1593

1594 1595
      fprintf(fp, "      stbName:           %s\n",
              g_Dbs.db[i].superTbls[j].sTblName);
1596 1597 1598

      if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) {
        fprintf(fp, "      autoCreateTable:   %s\n",  "no");
1599 1600
      } else if (AUTO_CREATE_SUBTBL
              == g_Dbs.db[i].superTbls[j].autoCreateTable) {
1601 1602 1603 1604
        fprintf(fp, "      autoCreateTable:   %s\n",  "yes");
      } else {
        fprintf(fp, "      autoCreateTable:   %s\n",  "error");
      }
1605

1606 1607
      if (TBL_NO_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) {
        fprintf(fp, "      childTblExists:    %s\n",  "no");
1608 1609
      } else if (TBL_ALREADY_EXISTS
              == g_Dbs.db[i].superTbls[j].childTblExists) {
1610 1611 1612 1613
        fprintf(fp, "      childTblExists:    %s\n",  "yes");
      } else {
        fprintf(fp, "      childTblExists:    %s\n",  "error");
      }
1614

1615
      fprintf(fp, "      childTblCount:     %"PRId64"\n",
1616 1617 1618 1619 1620 1621 1622
              g_Dbs.db[i].superTbls[j].childTblCount);
      fprintf(fp, "      childTblPrefix:    %s\n",
              g_Dbs.db[i].superTbls[j].childTblPrefix);
      fprintf(fp, "      dataSource:        %s\n",
              g_Dbs.db[i].superTbls[j].dataSource);
      fprintf(fp, "      insertMode:        %s\n",
              g_Dbs.db[i].superTbls[j].insertMode);
1623
      fprintf(fp, "      insertRows:        %"PRId64"\n",
1624
              g_Dbs.db[i].superTbls[j].insertRows);
1625
      fprintf(fp, "      interlace rows:    %"PRIu64"\n",
1626
              g_Dbs.db[i].superTbls[j].interlaceRows);
1627
      if (g_Dbs.db[i].superTbls[j].interlaceRows > 0) {
1628
        fprintf(fp, "      stable insert interval:   %"PRIu64"\n",
1629
                g_Dbs.db[i].superTbls[j].insertInterval);
1630
      }
1631
/*
1632
      if (0 == g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl) {
1633
        fprintf(fp, "      multiThreadWriteOneTbl:  no\n");
1634
      }else {
1635
        fprintf(fp, "      multiThreadWriteOneTbl:  yes\n");
1636
      }
1637
      */
1638
      fprintf(fp, "      interlaceRows:     %"PRIu64"\n",
1639
              g_Dbs.db[i].superTbls[j].interlaceRows);
1640 1641 1642 1643
      fprintf(fp, "      disorderRange:     %d\n",
              g_Dbs.db[i].superTbls[j].disorderRange);
      fprintf(fp, "      disorderRatio:     %d\n",
              g_Dbs.db[i].superTbls[j].disorderRatio);
1644
      fprintf(fp, "      maxSqlLen:         %"PRIu64"\n",
1645
              g_Dbs.db[i].superTbls[j].maxSqlLen);
1646

1647 1648 1649 1650
      fprintf(fp, "      timeStampStep:     %"PRId64"\n",
              g_Dbs.db[i].superTbls[j].timeStampStep);
      fprintf(fp, "      startTimestamp:    %s\n",
              g_Dbs.db[i].superTbls[j].startTimestamp);
1651 1652 1653 1654 1655 1656
      fprintf(fp, "      sampleFormat:      %s\n",
              g_Dbs.db[i].superTbls[j].sampleFormat);
      fprintf(fp, "      sampleFile:        %s\n",
              g_Dbs.db[i].superTbls[j].sampleFile);
      fprintf(fp, "      tagsFile:          %s\n",
              g_Dbs.db[i].superTbls[j].tagsFile);
1657

1658 1659
      fprintf(fp, "      columnCount:       %d\n        ",
              g_Dbs.db[i].superTbls[j].columnCount);
1660 1661
      for (int k = 0; k < g_Dbs.db[i].superTbls[j].columnCount; k++) {
        //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].columns[k].dataType, g_Dbs.db[i].superTbls[j].columns[k].dataLen);
1662 1663 1664
        if ((0 == strncasecmp(
                        g_Dbs.db[i].superTbls[j].columns[k].dataType,
                        "binary", strlen("binary")))
1665 1666
                || (0 == strncasecmp(
                        g_Dbs.db[i].superTbls[j].columns[k].dataType,
1667 1668 1669 1670
                        "nchar", strlen("nchar")))) {
          fprintf(fp, "column[%d]:%s(%d) ", k,
                  g_Dbs.db[i].superTbls[j].columns[k].dataType,
                  g_Dbs.db[i].superTbls[j].columns[k].dataLen);
1671
        } else {
1672 1673
          fprintf(fp, "column[%d]:%s ",
                  k, g_Dbs.db[i].superTbls[j].columns[k].dataType);
1674 1675 1676
        }
      }
      fprintf(fp, "\n");
1677 1678 1679

      fprintf(fp, "      tagCount:            %d\n        ",
              g_Dbs.db[i].superTbls[j].tagCount);
1680 1681
      for (int k = 0; k < g_Dbs.db[i].superTbls[j].tagCount; k++) {
        //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].tags[k].dataType, g_Dbs.db[i].superTbls[j].tags[k].dataLen);
1682 1683 1684 1685
        if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
                        "binary", strlen("binary")))
                || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
                        "nchar", strlen("nchar")))) {
1686 1687
          fprintf(fp, "tag[%d]:%s(%d) ",
                  k, g_Dbs.db[i].superTbls[j].tags[k].dataType,
1688
                  g_Dbs.db[i].superTbls[j].tags[k].dataLen);
1689 1690
        } else {
          fprintf(fp, "tag[%d]:%s ", k, g_Dbs.db[i].superTbls[j].tags[k].dataType);
1691
        }
1692 1693 1694 1695 1696
      }
      fprintf(fp, "\n");
    }
    fprintf(fp, "\n");
  }
1697

1698
  SHOW_PARSE_RESULT_END_TO_FILE(fp);
1699 1700 1701
}

static void printfQueryMeta() {
1702

1703
  SHOW_PARSE_RESULT_START();
1704

1705 1706
  printf("host:                    \033[33m%s:%u\033[0m\n",
          g_queryInfo.host, g_queryInfo.port);
1707 1708 1709 1710
  printf("user:                    \033[33m%s\033[0m\n", g_queryInfo.user);
  printf("database name:           \033[33m%s\033[0m\n", g_queryInfo.dbName);

  printf("\n");
1711 1712 1713 1714

  if ((SUBSCRIBE_TEST == g_args.test_mode) || (QUERY_TEST == g_args.test_mode)) {
    printf("specified table query info:                   \n");
    printf("sqlCount:       \033[33m%"PRIu64"\033[0m\n",
1715
      g_queryInfo.specifiedQueryInfo.sqlCount);
1716 1717 1718
    if (g_queryInfo.specifiedQueryInfo.sqlCount > 0) {
      printf("specified tbl query times:\n");
      printf("                \033[33m%"PRIu64"\033[0m\n",
1719
      g_queryInfo.specifiedQueryInfo.queryTimes);
1720 1721 1722 1723 1724 1725
      printf("query interval: \033[33m%"PRIu64" ms\033[0m\n",
        g_queryInfo.specifiedQueryInfo.queryInterval);
      printf("top query times:\033[33m%"PRIu64"\033[0m\n", g_args.query_times);
      printf("concurrent:     \033[33m%"PRIu64"\033[0m\n",
      g_queryInfo.specifiedQueryInfo.concurrent);
      printf("mod:            \033[33m%s\033[0m\n",
1726
        (g_queryInfo.specifiedQueryInfo.asyncMode)?"async":"sync");
1727
      printf("interval:       \033[33m%"PRIu64"\033[0m\n",
1728
        g_queryInfo.specifiedQueryInfo.subscribeInterval);
1729
      printf("restart:        \033[33m%d\033[0m\n",
1730
        g_queryInfo.specifiedQueryInfo.subscribeRestart);
1731
      printf("keepProgress:   \033[33m%d\033[0m\n",
1732
        g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
1733

1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749
      for (uint64_t i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) {
        printf("  sql[%"PRIu64"]: \033[33m%s\033[0m\n",
            i, g_queryInfo.specifiedQueryInfo.sql[i]);
      }
      printf("\n");
    }

    printf("super table query info:\n");
    printf("sqlCount:       \033[33m%"PRIu64"\033[0m\n",
      g_queryInfo.superQueryInfo.sqlCount);

    if (g_queryInfo.superQueryInfo.sqlCount > 0) {
      printf("query interval: \033[33m%"PRIu64"\033[0m\n",
        g_queryInfo.superQueryInfo.queryInterval);
      printf("threadCnt:      \033[33m%d\033[0m\n",
        g_queryInfo.superQueryInfo.threadCnt);
1750
      printf("childTblCount:  \033[33m%"PRId64"\033[0m\n",
1751 1752 1753 1754 1755 1756 1757
        g_queryInfo.superQueryInfo.childTblCount);
      printf("stable name:    \033[33m%s\033[0m\n",
        g_queryInfo.superQueryInfo.sTblName);
      printf("stb query times:\033[33m%"PRIu64"\033[0m\n",
        g_queryInfo.superQueryInfo.queryTimes);

      printf("mod:            \033[33m%s\033[0m\n",
1758
        (g_queryInfo.superQueryInfo.asyncMode)?"async":"sync");
1759
      printf("interval:       \033[33m%"PRIu64"\033[0m\n",
1760
        g_queryInfo.superQueryInfo.subscribeInterval);
1761
      printf("restart:        \033[33m%d\033[0m\n",
1762
        g_queryInfo.superQueryInfo.subscribeRestart);
1763
      printf("keepProgress:   \033[33m%d\033[0m\n",
1764 1765
        g_queryInfo.superQueryInfo.subscribeKeepProgress);

1766 1767 1768 1769 1770 1771
      for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) {
        printf("  sql[%d]: \033[33m%s\033[0m\n",
            i, g_queryInfo.superQueryInfo.sql[i]);
      }
      printf("\n");
    }
1772
  }
1773

1774
  SHOW_PARSE_RESULT_END();
1775 1776
}

1777
static char* formatTimestamp(char* buf, int64_t val, int precision) {
1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808
  time_t tt;
  if (precision == TSDB_TIME_PRECISION_MICRO) {
    tt = (time_t)(val / 1000000);
  } else {
    tt = (time_t)(val / 1000);
  }

/* comment out as it make testcases like select_with_tags.sim fail.
  but in windows, this may cause the call to localtime crash if tt < 0,
  need to find a better solution.
  if (tt < 0) {
    tt = 0;
  }
  */

#ifdef WINDOWS
  if (tt < 0) tt = 0;
#endif

  struct tm* ptm = localtime(&tt);
  size_t pos = strftime(buf, 32, "%Y-%m-%d %H:%M:%S", ptm);

  if (precision == TSDB_TIME_PRECISION_MICRO) {
    sprintf(buf + pos, ".%06d", (int)(val % 1000000));
  } else {
    sprintf(buf + pos, ".%03d", (int)(val % 1000));
  }

  return buf;
}

1809 1810 1811
static void xDumpFieldToFile(FILE* fp, const char* val,
        TAOS_FIELD* field, int32_t length, int precision) {

1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846
  if (val == NULL) {
    fprintf(fp, "%s", TSDB_DATA_NULL_STR);
    return;
  }

  char buf[TSDB_MAX_BYTES_PER_ROW];
  switch (field->type) {
    case TSDB_DATA_TYPE_BOOL:
      fprintf(fp, "%d", ((((int32_t)(*((char *)val))) == 1) ? 1 : 0));
      break;
    case TSDB_DATA_TYPE_TINYINT:
      fprintf(fp, "%d", *((int8_t *)val));
      break;
    case TSDB_DATA_TYPE_SMALLINT:
      fprintf(fp, "%d", *((int16_t *)val));
      break;
    case TSDB_DATA_TYPE_INT:
      fprintf(fp, "%d", *((int32_t *)val));
      break;
    case TSDB_DATA_TYPE_BIGINT:
      fprintf(fp, "%" PRId64, *((int64_t *)val));
      break;
    case TSDB_DATA_TYPE_FLOAT:
      fprintf(fp, "%.5f", GET_FLOAT_VAL(val));
      break;
    case TSDB_DATA_TYPE_DOUBLE:
      fprintf(fp, "%.9f", GET_DOUBLE_VAL(val));
      break;
    case TSDB_DATA_TYPE_BINARY:
    case TSDB_DATA_TYPE_NCHAR:
      memcpy(buf, val, length);
      buf[length] = 0;
      fprintf(fp, "\'%s\'", buf);
      break;
    case TSDB_DATA_TYPE_TIMESTAMP:
1847
      formatTimestamp(buf, *(int64_t*)val, precision);
1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862
      fprintf(fp, "'%s'", buf);
      break;
    default:
      break;
  }
}

static int xDumpResultToFile(const char* fname, TAOS_RES* tres) {
  TAOS_ROW row = taos_fetch_row(tres);
  if (row == NULL) {
    return 0;
  }

  FILE* fp = fopen(fname, "at");
  if (fp == NULL) {
1863
    errorPrint("%s() LN%d, failed to open file: %s\n", __func__, __LINE__, fname);
1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877
    return -1;
  }

  int num_fields = taos_num_fields(tres);
  TAOS_FIELD *fields = taos_fetch_fields(tres);
  int precision = taos_result_precision(tres);

  for (int col = 0; col < num_fields; col++) {
    if (col > 0) {
      fprintf(fp, ",");
    }
    fprintf(fp, "%s", fields[col].name);
  }
  fputc('\n', fp);
1878

1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898
  int numOfRows = 0;
  do {
    int32_t* length = taos_fetch_lengths(tres);
    for (int i = 0; i < num_fields; i++) {
      if (i > 0) {
        fputc(',', fp);
      }
      xDumpFieldToFile(fp, (const char*)row[i], fields +i, length[i], precision);
    }
    fputc('\n', fp);

    numOfRows++;
    row = taos_fetch_row(tres);
  } while( row != NULL);

  fclose(fp);

  return numOfRows;
}

1899 1900
static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) {
  TAOS_RES * res;
1901 1902
  TAOS_ROW row = NULL;
  int count = 0;
1903 1904

  res = taos_query(taos, "show databases;");
1905
  int32_t code = taos_errno(res);
1906

1907
  if (code != 0) {
1908
    errorPrint( "failed to run <show databases>, reason: %s\n", taos_errstr(res));
1909 1910 1911 1912 1913
    return -1;
  }

  TAOS_FIELD *fields = taos_fetch_fields(res);

1914
  while((row = taos_fetch_row(res)) != NULL) {
1915
    // sys database name : 'log'
1916 1917 1918 1919
    if (strncasecmp(row[TSDB_SHOW_DB_NAME_INDEX], "log",
                fields[TSDB_SHOW_DB_NAME_INDEX].bytes) == 0) {
      continue;
    }
1920 1921 1922

    dbInfos[count] = (SDbInfo *)calloc(1, sizeof(SDbInfo));
    if (dbInfos[count] == NULL) {
1923
      errorPrint( "failed to allocate memory for some dbInfo[%d]\n", count);
1924 1925 1926
      return -1;
    }

1927 1928
    tstrncpy(dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX],
            fields[TSDB_SHOW_DB_NAME_INDEX].bytes);
1929
    formatTimestamp(dbInfos[count]->create_time,
1930 1931
            *(int64_t*)row[TSDB_SHOW_DB_CREATED_TIME_INDEX],
            TSDB_TIME_PRECISION_MILLI);
1932
    dbInfos[count]->ntables = *((int64_t *)row[TSDB_SHOW_DB_NTABLES_INDEX]);
1933
    dbInfos[count]->vgroups = *((int32_t *)row[TSDB_SHOW_DB_VGROUPS_INDEX]);
1934 1935
    dbInfos[count]->replica = *((int16_t *)row[TSDB_SHOW_DB_REPLICA_INDEX]);
    dbInfos[count]->quorum = *((int16_t *)row[TSDB_SHOW_DB_QUORUM_INDEX]);
1936
    dbInfos[count]->days = *((int16_t *)row[TSDB_SHOW_DB_DAYS_INDEX]);
1937

1938
    tstrncpy(dbInfos[count]->keeplist, (char *)row[TSDB_SHOW_DB_KEEP_INDEX],
1939
            fields[TSDB_SHOW_DB_KEEP_INDEX].bytes);
1940 1941 1942 1943 1944 1945 1946
    dbInfos[count]->cache = *((int32_t *)row[TSDB_SHOW_DB_CACHE_INDEX]);
    dbInfos[count]->blocks = *((int32_t *)row[TSDB_SHOW_DB_BLOCKS_INDEX]);
    dbInfos[count]->minrows = *((int32_t *)row[TSDB_SHOW_DB_MINROWS_INDEX]);
    dbInfos[count]->maxrows = *((int32_t *)row[TSDB_SHOW_DB_MAXROWS_INDEX]);
    dbInfos[count]->wallevel = *((int8_t *)row[TSDB_SHOW_DB_WALLEVEL_INDEX]);
    dbInfos[count]->fsync = *((int32_t *)row[TSDB_SHOW_DB_FSYNC_INDEX]);
    dbInfos[count]->comp = (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_COMP_INDEX]));
1947 1948
    dbInfos[count]->cachelast =
      (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_CACHELAST_INDEX]));
1949

1950
    tstrncpy(dbInfos[count]->precision,
1951
            (char *)row[TSDB_SHOW_DB_PRECISION_INDEX],
1952
            fields[TSDB_SHOW_DB_PRECISION_INDEX].bytes);
1953
    dbInfos[count]->update = *((int8_t *)row[TSDB_SHOW_DB_UPDATE_INDEX]);
1954
    tstrncpy(dbInfos[count]->status, (char *)row[TSDB_SHOW_DB_STATUS_INDEX],
1955
            fields[TSDB_SHOW_DB_STATUS_INDEX].bytes);
1956

1957 1958
    count++;
    if (count > MAX_DATABASE_COUNT) {
1959 1960
      errorPrint("%s() LN%d, The database count overflow than %d\n",
         __func__, __LINE__, MAX_DATABASE_COUNT);
1961 1962 1963 1964 1965 1966 1967
      break;
    }
  }

  return count;
}

1968 1969
static void printfDbInfoForQueryToFile(
        char* filename, SDbInfo* dbInfos, int index) {
1970

1971
  if (filename[0] == 0)
1972
      return;
1973 1974 1975

  FILE *fp = fopen(filename, "at");
  if (fp == NULL) {
1976
    errorPrint( "failed to open file: %s\n", filename);
1977
    return;
1978 1979 1980 1981 1982
  }

  fprintf(fp, "================ database[%d] ================\n", index);
  fprintf(fp, "name: %s\n", dbInfos->name);
  fprintf(fp, "created_time: %s\n", dbInfos->create_time);
1983
  fprintf(fp, "ntables: %"PRId64"\n", dbInfos->ntables);
1984
  fprintf(fp, "vgroups: %d\n", dbInfos->vgroups);
1985 1986
  fprintf(fp, "replica: %d\n", dbInfos->replica);
  fprintf(fp, "quorum: %d\n", dbInfos->quorum);
1987 1988
  fprintf(fp, "days: %d\n", dbInfos->days);
  fprintf(fp, "keep0,keep1,keep(D): %s\n", dbInfos->keeplist);
1989 1990 1991 1992 1993 1994 1995
  fprintf(fp, "cache(MB): %d\n", dbInfos->cache);
  fprintf(fp, "blocks: %d\n", dbInfos->blocks);
  fprintf(fp, "minrows: %d\n", dbInfos->minrows);
  fprintf(fp, "maxrows: %d\n", dbInfos->maxrows);
  fprintf(fp, "wallevel: %d\n", dbInfos->wallevel);
  fprintf(fp, "fsync: %d\n", dbInfos->fsync);
  fprintf(fp, "comp: %d\n", dbInfos->comp);
1996 1997
  fprintf(fp, "cachelast: %d\n", dbInfos->cachelast);
  fprintf(fp, "precision: %s\n", dbInfos->precision);
1998
  fprintf(fp, "update: %d\n", dbInfos->update);
1999
  fprintf(fp, "status: %s\n", dbInfos->status);
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
  fprintf(fp, "\n");

  fclose(fp);
}

static void printfQuerySystemInfo(TAOS * taos) {
  char filename[MAX_QUERY_SQL_LENGTH+1] = {0};
  char buffer[MAX_QUERY_SQL_LENGTH+1] = {0};
  TAOS_RES* res;

  time_t t;
  struct tm* lt;
  time(&t);
  lt = localtime(&t);
2014 2015 2016 2017
  snprintf(filename, MAX_QUERY_SQL_LENGTH, "querySystemInfo-%d-%d-%d %d:%d:%d",
          lt->tm_year+1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min,
          lt->tm_sec);

2018 2019
  // show variables
  res = taos_query(taos, "show variables;");
2020
  //appendResultToFile(res, filename);
2021 2022 2023 2024 2025
  xDumpResultToFile(filename, res);

  // show dnodes
  res = taos_query(taos, "show dnodes;");
  xDumpResultToFile(filename, res);
2026
  //appendResultToFile(res, filename);
2027

2028 2029 2030 2031
  // show databases
  res = taos_query(taos, "show databases;");
  SDbInfo** dbInfos = (SDbInfo **)calloc(MAX_DATABASE_COUNT, sizeof(SDbInfo *));
  if (dbInfos == NULL) {
2032
    errorPrint("%s() LN%d, failed to allocate memory\n", __func__, __LINE__);
2033 2034 2035
    return;
  }
  int dbCount = getDbFromServer(taos, dbInfos);
2036 2037 2038 2039
  if (dbCount <= 0) {
      free(dbInfos);
      return;
  }
2040 2041

  for (int i = 0; i < dbCount; i++) {
2042
    // printf database info
2043
    printfDbInfoForQueryToFile(filename, dbInfos[i], i);
2044

2045 2046 2047 2048
    // show db.vgroups
    snprintf(buffer, MAX_QUERY_SQL_LENGTH, "show %s.vgroups;", dbInfos[i]->name);
    res = taos_query(taos, buffer);
    xDumpResultToFile(filename, res);
2049

2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060
    // show db.stables
    snprintf(buffer, MAX_QUERY_SQL_LENGTH, "show %s.stables;", dbInfos[i]->name);
    res = taos_query(taos, buffer);
    xDumpResultToFile(filename, res);

    free(dbInfos[i]);
  }

  free(dbInfos);
}

2061 2062
static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port,
        char* sqlstr, char *resultFile)
2063
{
2064
    char *req_fmt = "POST %s HTTP/1.1\r\nHost: %s:%d\r\nAccept: */*\r\nAuthorization: Basic %s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s";
2065 2066 2067

    char *url = "/rest/sql";

2068
    int bytes, sent, received, req_str_len, resp_len;
2069 2070 2071
    char *request_buf;
    char response_buf[RESP_BUF_LEN];
    uint16_t rest_port = port + TSDB_PORT_HTTP;
2072

2073 2074 2075
    int req_buf_len = strlen(sqlstr) + REQ_EXTRA_BUF_LEN;

    request_buf = malloc(req_buf_len);
2076 2077 2078 2079
    if (NULL == request_buf) {
      errorPrint("%s", "ERROR, cannot allocate memory.\n");
      exit(EXIT_FAILURE);
    }
2080

2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091
    char userpass_buf[INPUT_BUF_LEN];
    int mod_table[] = {0, 2, 1};

    static char base64[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
      'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
      'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
      'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
      'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
      'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
      'w', 'x', 'y', 'z', '0', '1', '2', '3',
      '4', '5', '6', '7', '8', '9', '+', '/'};
2092

2093 2094 2095 2096 2097 2098
    snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s",
        g_Dbs.user, g_Dbs.password);
    size_t userpass_buf_len = strlen(userpass_buf);
    size_t encoded_len = 4 * ((userpass_buf_len +2) / 3);

    char base64_buf[INPUT_BUF_LEN];
2099
#ifdef WINDOWS
2100
    WSADATA wsaData;
2101
    WSAStartup(MAKEWORD(2, 2), &wsaData);
2102 2103 2104 2105
    SOCKET sockfd;
#else
    int sockfd;
#endif
2106
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
2107
    if (sockfd < 0) {
2108
#ifdef WINDOWS
2109
        errorPrint( "Could not create socket : %d" , WSAGetLastError());
2110
#endif
2111
        debugPrint("%s() LN%d, sockfd=%d\n", __func__, __LINE__, sockfd);
2112
        free(request_buf);
2113
        ERROR_EXIT("ERROR opening socket");
2114
    }
2115

2116
    int retConn = connect(sockfd, (struct sockaddr *)pServAddr, sizeof(struct sockaddr));
2117 2118
    debugPrint("%s() LN%d connect() return %d\n", __func__, __LINE__, retConn);
    if (retConn < 0) {
2119
        free(request_buf);
2120
        ERROR_EXIT("ERROR connecting");
2121
    }
2122

2123 2124 2125
    memset(base64_buf, 0, INPUT_BUF_LEN);

    for (int n = 0, m = 0; n < userpass_buf_len;) {
2126
      uint32_t oct_a = n < userpass_buf_len ?
2127
        (unsigned char) userpass_buf[n++]:0;
2128
      uint32_t oct_b = n < userpass_buf_len ?
2129
        (unsigned char) userpass_buf[n++]:0;
2130
      uint32_t oct_c = n < userpass_buf_len ?
2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142
        (unsigned char) userpass_buf[n++]:0;
      uint32_t triple = (oct_a << 0x10) + (oct_b << 0x08) + oct_c;

      base64_buf[m++] = base64[(triple >> 3* 6) & 0x3f];
      base64_buf[m++] = base64[(triple >> 2* 6) & 0x3f];
      base64_buf[m++] = base64[(triple >> 1* 6) & 0x3f];
      base64_buf[m++] = base64[(triple >> 0* 6) & 0x3f];
    }

    for (int l = 0; l < mod_table[userpass_buf_len % 3]; l++)
      base64_buf[encoded_len - 1 - l] = '=';

2143 2144
    debugPrint("%s() LN%d: auth string base64 encoded: %s\n",
            __func__, __LINE__, base64_buf);
2145 2146
    char *auth = base64_buf;

2147 2148 2149
    int r = snprintf(request_buf,
            req_buf_len,
            req_fmt, url, host, rest_port,
2150 2151 2152 2153 2154
            auth, strlen(sqlstr), sqlstr);
    if (r >= req_buf_len) {
        free(request_buf);
        ERROR_EXIT("ERROR too long request");
    }
2155
    verbosePrint("%s() LN%d: Request:\n%s\n", __func__, __LINE__, request_buf);
2156

2157
    req_str_len = strlen(request_buf);
2158 2159
    sent = 0;
    do {
2160 2161 2162
#ifdef WINDOWS
        bytes = send(sockfd, request_buf + sent, req_str_len - sent, 0);
#else
2163
        bytes = write(sockfd, request_buf + sent, req_str_len - sent);
2164
#endif
2165
        if (bytes < 0)
2166
            ERROR_EXIT("ERROR writing message to socket");
2167 2168 2169
        if (bytes == 0)
            break;
        sent+=bytes;
2170
    } while(sent < req_str_len);
2171

2172 2173
    memset(response_buf, 0, RESP_BUF_LEN);
    resp_len = sizeof(response_buf) - 1;
2174 2175
    received = 0;
    do {
2176 2177 2178
#ifdef WINDOWS
        bytes = recv(sockfd, response_buf + received, resp_len - received, 0);
#else
2179
        bytes = read(sockfd, response_buf + received, resp_len - received);
2180
#endif
2181 2182
        if (bytes < 0) {
            free(request_buf);
2183
            ERROR_EXIT("ERROR reading response from socket");
2184
        }
2185 2186
        if (bytes == 0)
            break;
2187
        received += bytes;
2188
    } while(received < resp_len);
2189

2190 2191
    if (received == resp_len) {
        free(request_buf);
2192
        ERROR_EXIT("ERROR storing complete response from socket");
2193
    }
2194

2195
    response_buf[RESP_BUF_LEN - 1] = '\0';
2196 2197
    printf("Response:\n%s\n", response_buf);

2198 2199 2200 2201
    if (resultFile) {
       appendResultBufToFile(response_buf, resultFile);
    }

2202
    free(request_buf);
2203 2204 2205 2206
#ifdef WINDOWS
    closesocket(sockfd);
    WSACleanup();
#else
2207
    close(sockfd);
2208
#endif
2209 2210 2211 2212

    return 0;
}

2213
static char* getTagValueFromTagSample(SSuperTable* stbInfo, int tagUsePos) {
2214 2215
  char*  dataBuf = (char*)calloc(TSDB_MAX_SQL_LEN+1, 1);
  if (NULL == dataBuf) {
2216 2217
    errorPrint("%s() LN%d, calloc failed! size:%d\n",
        __func__, __LINE__, TSDB_MAX_SQL_LEN+1);
2218 2219
    return NULL;
  }
2220

2221
  int    dataLen = 0;
2222 2223 2224
  dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
          "(%s)", stbInfo->tagDataBuf + stbInfo->lenOfTagOfOneRow * tagUsePos);

2225 2226 2227
  return dataBuf;
}

2228
static char* generateTagVaulesForStb(SSuperTable* stbInfo, int32_t tableSeq) {
2229 2230 2231 2232 2233 2234 2235 2236 2237
  char*  dataBuf = (char*)calloc(TSDB_MAX_SQL_LEN+1, 1);
  if (NULL == dataBuf) {
    printf("calloc failed! size:%d\n", TSDB_MAX_SQL_LEN+1);
    return NULL;
  }

  int    dataLen = 0;
  dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, "(");
  for (int i = 0; i < stbInfo->tagCount; i++) {
2238 2239
    if ((0 == strncasecmp(stbInfo->tags[i].dataType, "binary", strlen("binary")))
            || (0 == strncasecmp(stbInfo->tags[i].dataType, "nchar", strlen("nchar")))) {
2240
      if (stbInfo->tags[i].dataLen > TSDB_MAX_BINARY_LEN) {
2241 2242
        printf("binary or nchar length overflow, max size:%u\n",
                (uint32_t)TSDB_MAX_BINARY_LEN);
2243 2244 2245
        tmfree(dataBuf);
        return NULL;
      }
2246

2247 2248
      int tagBufLen = stbInfo->tags[i].dataLen + 1;
      char* buf = (char*)calloc(tagBufLen, 1);
2249 2250 2251 2252 2253
      if (NULL == buf) {
        printf("calloc failed! size:%d\n", stbInfo->tags[i].dataLen);
        tmfree(dataBuf);
        return NULL;
      }
2254 2255 2256 2257 2258 2259 2260

      if (tableSeq % 2) {
        tstrncpy(buf, "beijing", tagBufLen);
      } else {
        tstrncpy(buf, "shanghai", tagBufLen);
      }
      //rand_string(buf, stbInfo->tags[i].dataLen);
2261 2262
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "\'%s\', ", buf);
2263
      tmfree(buf);
2264 2265 2266
    } else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "int", strlen("int"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2267
              "%d, ", tableSeq);
2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295
    } else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "bigint", strlen("bigint"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "%"PRId64", ", rand_bigint());
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "float", strlen("float"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "%f, ", rand_float());
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "double", strlen("double"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "%f, ", rand_double());
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "smallint", strlen("smallint"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "%d, ", rand_smallint());
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "tinyint", strlen("tinyint"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "%d, ", rand_tinyint());
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "bool", strlen("bool"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "%d, ", rand_bool());
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
                "timestamp", strlen("timestamp"))) {
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
              "%"PRId64", ", rand_bigint());
2296 2297 2298 2299 2300 2301
    }  else {
      printf("No support data type: %s\n", stbInfo->tags[i].dataType);
      tmfree(dataBuf);
      return NULL;
    }
  }
2302

2303
  dataLen -= 2;
2304
  dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, ")");
2305 2306 2307
  return dataBuf;
}

2308
static int calcRowLen(SSuperTable*  superTbls) {
2309 2310
  int colIndex;
  int  lenOfOneRow = 0;
2311

2312 2313
  for (colIndex = 0; colIndex < superTbls->columnCount; colIndex++) {
    char* dataType = superTbls->columns[colIndex].dataType;
2314

2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330
    if (strcasecmp(dataType, "BINARY") == 0) {
      lenOfOneRow += superTbls->columns[colIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "NCHAR") == 0) {
      lenOfOneRow += superTbls->columns[colIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "INT") == 0)  {
      lenOfOneRow += 11;
    } else if (strcasecmp(dataType, "BIGINT") == 0)  {
      lenOfOneRow += 21;
    } else if (strcasecmp(dataType, "SMALLINT") == 0)  {
      lenOfOneRow += 6;
    } else if (strcasecmp(dataType, "TINYINT") == 0)  {
      lenOfOneRow += 4;
    } else if (strcasecmp(dataType, "BOOL") == 0)  {
      lenOfOneRow += 6;
    } else if (strcasecmp(dataType, "FLOAT") == 0) {
      lenOfOneRow += 22;
2331
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
2332
      lenOfOneRow += 42;
2333
    }  else if (strcasecmp(dataType, "TIMESTAMP") == 0) {
2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346
      lenOfOneRow += 21;
    } else {
      printf("get error data type : %s\n", dataType);
      exit(-1);
    }
  }

  superTbls->lenOfOneRow = lenOfOneRow + 20; // timestamp

  int tagIndex;
  int lenOfTagOfOneRow = 0;
  for (tagIndex = 0; tagIndex < superTbls->tagCount; tagIndex++) {
    char* dataType = superTbls->tags[tagIndex].dataType;
2347

2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363
    if (strcasecmp(dataType, "BINARY") == 0) {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "NCHAR") == 0) {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "INT") == 0)  {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 11;
    } else if (strcasecmp(dataType, "BIGINT") == 0)  {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 21;
    } else if (strcasecmp(dataType, "SMALLINT") == 0)  {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6;
    } else if (strcasecmp(dataType, "TINYINT") == 0)  {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 4;
    } else if (strcasecmp(dataType, "BOOL") == 0)  {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 6;
    } else if (strcasecmp(dataType, "FLOAT") == 0) {
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 22;
2364
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
2365 2366 2367 2368 2369 2370 2371 2372
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 42;
    } else {
      printf("get error tag type : %s\n", dataType);
      exit(-1);
    }
  }

  superTbls->lenOfTagOfOneRow = lenOfTagOfOneRow;
2373

2374 2375 2376 2377
  return 0;
}


2378 2379
static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos,
        char* dbName, char* sTblName, char** childTblNameOfSuperTbl,
2380
        int64_t* childTblCountOfSuperTbl, int64_t limit, uint64_t offset) {
2381

2382
  char command[BUFFER_SIZE] = "\0";
2383 2384
  char limitBuf[100] = "\0";

2385
  TAOS_RES * res;
2386 2387 2388
  TAOS_ROW row = NULL;

  char* childTblName = *childTblNameOfSuperTbl;
2389 2390

  if (offset >= 0) {
2391
    snprintf(limitBuf, 100, " limit %"PRId64" offset %"PRIu64"",
2392
            limit, offset);
2393 2394
  }

2395
  //get all child table name use cmd: select tbname from superTblName;
2396 2397
  snprintf(command, BUFFER_SIZE, "select tbname from %s.%s %s",
          dbName, sTblName, limitBuf);
2398

2399
  res = taos_query(taos, command);
2400 2401 2402 2403
  int32_t code = taos_errno(res);
  if (code != 0) {
    taos_free_result(res);
    taos_close(taos);
2404 2405
    errorPrint("%s() LN%d, failed to run command %s\n",
           __func__, __LINE__, command);
2406 2407 2408
    exit(-1);
  }

2409 2410
  int64_t childTblCount = (limit < 0)?10000:limit;
  int64_t count = 0;
2411 2412 2413 2414 2415 2416 2417 2418 2419 2420
  if (childTblName == NULL) {
    childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN);
    if (NULL ==  childTblName) {
    taos_free_result(res);
        taos_close(taos);
        errorPrint("%s() LN%d, failed to allocate memory!\n", __func__, __LINE__);
        exit(-1);
    }
  }

2421
  char* pTblName = childTblName;
2422
  while((row = taos_fetch_row(res)) != NULL) {
2423
    int32_t* len = taos_fetch_lengths(res);
2424
    tstrncpy(pTblName, (char *)row[0], len[0]+1);
2425 2426 2427
    //printf("==== sub table name: %s\n", pTblName);
    count++;
    if (count >= childTblCount - 1) {
2428 2429
      char *tmp = realloc(childTblName,
              (size_t)childTblCount*1.5*TSDB_TABLE_NAME_LEN+1);
2430 2431 2432
      if (tmp != NULL) {
        childTblName = tmp;
        childTblCount = (int)(childTblCount*1.5);
2433 2434
        memset(childTblName + count*TSDB_TABLE_NAME_LEN, 0,
                (size_t)((childTblCount-count)*TSDB_TABLE_NAME_LEN));
2435 2436
      } else {
        // exit, if allocate more memory failed
2437 2438
        errorPrint("%s() LN%d, realloc fail for save child table name of %s.%s\n",
               __func__, __LINE__, dbName, sTblName);
2439 2440 2441 2442 2443 2444
        tmfree(childTblName);
        taos_free_result(res);
        taos_close(taos);
        exit(-1);
      }
    }
2445
    pTblName = childTblName + count * TSDB_TABLE_NAME_LEN;
2446
  }
2447

2448 2449 2450 2451 2452 2453 2454
  *childTblCountOfSuperTbl = count;
  *childTblNameOfSuperTbl  = childTblName;

  taos_free_result(res);
  return 0;
}

2455 2456
static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName,
        char* sTblName, char** childTblNameOfSuperTbl,
2457
        int64_t* childTblCountOfSuperTbl) {
2458 2459 2460

    return getChildNameOfSuperTableWithLimitAndOffset(taos, dbName, sTblName,
            childTblNameOfSuperTbl, childTblCountOfSuperTbl,
2461
            -1, 0);
2462 2463
}

2464 2465
static int getSuperTableFromServer(TAOS * taos, char* dbName,
        SSuperTable*  superTbls) {
2466

2467
  char command[BUFFER_SIZE] = "\0";
2468
  TAOS_RES * res;
2469 2470
  TAOS_ROW row = NULL;
  int count = 0;
2471

2472
  //get schema use cmd: describe superTblName;
2473
  snprintf(command, BUFFER_SIZE, "describe %s.%s", dbName, superTbls->sTblName);
2474
  res = taos_query(taos, command);
2475 2476 2477
  int32_t code = taos_errno(res);
  if (code != 0) {
    printf("failed to run command %s\n", command);
2478
    taos_free_result(res);
2479 2480 2481 2482 2483 2484
    return -1;
  }

  int tagIndex = 0;
  int columnIndex = 0;
  TAOS_FIELD *fields = taos_fetch_fields(res);
2485
  while((row = taos_fetch_row(res)) != NULL) {
2486 2487 2488
    if (0 == count) {
      count++;
      continue;
2489
    }
2490 2491

    if (strcmp((char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], "TAG") == 0) {
2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502
      tstrncpy(superTbls->tags[tagIndex].field,
              (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
              fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
      tstrncpy(superTbls->tags[tagIndex].dataType,
              (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes);
      superTbls->tags[tagIndex].dataLen =
          *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
      tstrncpy(superTbls->tags[tagIndex].note,
              (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
2503
      tagIndex++;
2504
    } else {
2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515
      tstrncpy(superTbls->columns[columnIndex].field,
              (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
              fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
      tstrncpy(superTbls->columns[columnIndex].dataType,
              (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes);
      superTbls->columns[columnIndex].dataLen =
          *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
      tstrncpy(superTbls->columns[columnIndex].note,
              (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526
      columnIndex++;
    }
    count++;
  }

  superTbls->columnCount = columnIndex;
  superTbls->tagCount    = tagIndex;
  taos_free_result(res);

  calcRowLen(superTbls);

2527
/*
2528
  if (TBL_ALREADY_EXISTS == superTbls->childTblExists) {
2529
    //get all child table name use cmd: select tbname from superTblName;
2530 2531 2532
    int childTblCount = 10000;
    superTbls->childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN);
    if (superTbls->childTblName == NULL) {
2533
      errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__);
2534 2535
      return -1;
    }
2536
    getAllChildNameOfSuperTable(taos, dbName,
2537 2538 2539
            superTbls->sTblName,
            &superTbls->childTblName,
            &superTbls->childTblCount);
2540
  }
2541
  */
2542 2543 2544
  return 0;
}

2545 2546
static int createSuperTable(
        TAOS * taos, char* dbName,
2547
        SSuperTable*  superTbl) {
2548

2549
  char command[BUFFER_SIZE] = "\0";
2550

2551 2552 2553 2554 2555
  char cols[STRING_LEN] = "\0";
  int colIndex;
  int len = 0;

  int  lenOfOneRow = 0;
2556 2557 2558 2559 2560 2561 2562 2563 2564

  if (superTbl->columnCount == 0) {
    errorPrint("%s() LN%d, super table column count is %d\n",
            __func__, __LINE__, superTbl->columnCount);
    return -1;
  }

  for (colIndex = 0; colIndex < superTbl->columnCount; colIndex++) {
    char* dataType = superTbl->columns[colIndex].dataType;
2565

2566
    if (strcasecmp(dataType, "BINARY") == 0) {
2567 2568
      len += snprintf(cols + len, STRING_LEN - len,
          ", col%d %s(%d)", colIndex, "BINARY",
2569 2570
          superTbl->columns[colIndex].dataLen);
      lenOfOneRow += superTbl->columns[colIndex].dataLen + 3;
2571
    } else if (strcasecmp(dataType, "NCHAR") == 0) {
2572 2573
      len += snprintf(cols + len, STRING_LEN - len,
          ", col%d %s(%d)", colIndex, "NCHAR",
2574 2575
          superTbl->columns[colIndex].dataLen);
      lenOfOneRow += superTbl->columns[colIndex].dataLen + 3;
2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593
    } else if (strcasecmp(dataType, "INT") == 0)  {
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "INT");
      lenOfOneRow += 11;
    } else if (strcasecmp(dataType, "BIGINT") == 0)  {
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "BIGINT");
      lenOfOneRow += 21;
    } else if (strcasecmp(dataType, "SMALLINT") == 0)  {
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "SMALLINT");
      lenOfOneRow += 6;
    } else if (strcasecmp(dataType, "TINYINT") == 0)  {
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "TINYINT");
      lenOfOneRow += 4;
    } else if (strcasecmp(dataType, "BOOL") == 0)  {
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "BOOL");
      lenOfOneRow += 6;
    } else if (strcasecmp(dataType, "FLOAT") == 0) {
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "FLOAT");
      lenOfOneRow += 22;
2594
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
2595 2596
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "DOUBLE");
      lenOfOneRow += 42;
2597
    }  else if (strcasecmp(dataType, "TIMESTAMP") == 0) {
2598 2599 2600 2601
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "TIMESTAMP");
      lenOfOneRow += 21;
    } else {
      taos_close(taos);
2602 2603
      errorPrint("%s() LN%d, config error data type : %s\n",
         __func__, __LINE__, dataType);
2604 2605 2606 2607
      exit(-1);
    }
  }

2608 2609
  superTbl->lenOfOneRow = lenOfOneRow + 20; // timestamp
  //printf("%s.%s column count:%d, column length:%d\n\n", g_Dbs.db[i].dbName, g_Dbs.db[i].superTbl[j].sTblName, g_Dbs.db[i].superTbl[j].columnCount, lenOfOneRow);
2610 2611

  // save for creating child table
2612 2613 2614 2615
  superTbl->colsOfCreateChildTable = (char*)calloc(len+20, 1);
  if (NULL == superTbl->colsOfCreateChildTable) {
    errorPrint("%s() LN%d, Failed when calloc, size:%d",
           __func__, __LINE__, len+1);
2616 2617 2618 2619
    taos_close(taos);
    exit(-1);
  }

2620
  snprintf(superTbl->colsOfCreateChildTable, len+20, "(ts timestamp%s)", cols);
2621 2622
  verbosePrint("%s() LN%d: %s\n",
      __func__, __LINE__, superTbl->colsOfCreateChildTable);
2623

2624 2625 2626 2627 2628
  if (superTbl->tagCount == 0) {
    errorPrint("%s() LN%d, super table tag count is %d\n",
            __func__, __LINE__, superTbl->tagCount);
    return -1;
  }
2629

2630 2631 2632
  char tags[STRING_LEN] = "\0";
  int tagIndex;
  len = 0;
2633

2634 2635 2636 2637
  int lenOfTagOfOneRow = 0;
  len += snprintf(tags + len, STRING_LEN - len, "(");
  for (tagIndex = 0; tagIndex < superTbl->tagCount; tagIndex++) {
    char* dataType = superTbl->tags[tagIndex].dataType;
2638

2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676
    if (strcasecmp(dataType, "BINARY") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex,
              "BINARY", superTbl->tags[tagIndex].dataLen);
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "NCHAR") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex,
              "NCHAR", superTbl->tags[tagIndex].dataLen);
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "INT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
              "INT");
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 11;
    } else if (strcasecmp(dataType, "BIGINT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
              "BIGINT");
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 21;
    } else if (strcasecmp(dataType, "SMALLINT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
              "SMALLINT");
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 6;
    } else if (strcasecmp(dataType, "TINYINT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
              "TINYINT");
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 4;
    } else if (strcasecmp(dataType, "BOOL") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
              "BOOL");
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 6;
    } else if (strcasecmp(dataType, "FLOAT") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
              "FLOAT");
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 22;
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
              "DOUBLE");
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 42;
    } else {
      taos_close(taos);
2677 2678
      errorPrint("%s() LN%d, config error tag type : %s\n",
         __func__, __LINE__, dataType);
2679
      exit(-1);
2680 2681
    }
  }
2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698

  len -= 2;
  len += snprintf(tags + len, STRING_LEN - len, ")");

  superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow;

  snprintf(command, BUFFER_SIZE,
          "create table if not exists %s.%s (ts timestamp%s) tags %s",
          dbName, superTbl->sTblName, cols, tags);
  verbosePrint("%s() LN%d: %s\n", __func__, __LINE__, command);

  if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) {
      errorPrint( "create supertable %s failed!\n\n",
              superTbl->sTblName);
      return -1;
  }
  debugPrint("create supertable %s success!\n\n", superTbl->sTblName);
2699 2700 2701
  return 0;
}

2702
static int createDatabasesAndStables() {
2703 2704 2705 2706
  TAOS * taos = NULL;
  int    ret = 0;
  taos = taos_connect(g_Dbs.host, g_Dbs.user, g_Dbs.password, NULL, g_Dbs.port);
  if (taos == NULL) {
2707
    errorPrint( "Failed to connect to TDengine, reason:%s\n", taos_errstr(NULL));
2708
    return -1;
2709 2710 2711
  }
  char command[BUFFER_SIZE] = "\0";

2712
  for (int i = 0; i < g_Dbs.dbCount; i++) {
2713 2714
    if (g_Dbs.db[i].drop) {
      sprintf(command, "drop database if exists %s;", g_Dbs.db[i].dbName);
2715
      verbosePrint("%s() %d command: %s\n", __func__, __LINE__, command);
2716
      if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) {
2717 2718 2719 2720
        taos_close(taos);
        return -1;
      }

2721
      int dataLen = 0;
2722
      dataLen += snprintf(command + dataLen,
2723
          BUFFER_SIZE - dataLen, "create database if not exists %s", g_Dbs.db[i].dbName);
2724

2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794
      if (g_Dbs.db[i].dbCfg.blocks > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " blocks %d", g_Dbs.db[i].dbCfg.blocks);
      }
      if (g_Dbs.db[i].dbCfg.cache > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " cache %d", g_Dbs.db[i].dbCfg.cache);
      }
      if (g_Dbs.db[i].dbCfg.days > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " days %d", g_Dbs.db[i].dbCfg.days);
      }
      if (g_Dbs.db[i].dbCfg.keep > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " keep %d", g_Dbs.db[i].dbCfg.keep);
      }
      if (g_Dbs.db[i].dbCfg.quorum > 1) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " quorum %d", g_Dbs.db[i].dbCfg.quorum);
      }
      if (g_Dbs.db[i].dbCfg.replica > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " replica %d", g_Dbs.db[i].dbCfg.replica);
      }
      if (g_Dbs.db[i].dbCfg.update > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " update %d", g_Dbs.db[i].dbCfg.update);
      }
      //if (g_Dbs.db[i].dbCfg.maxtablesPerVnode > 0) {
      //  dataLen += snprintf(command + dataLen,
      //  BUFFER_SIZE - dataLen, "tables %d ", g_Dbs.db[i].dbCfg.maxtablesPerVnode);
      //}
      if (g_Dbs.db[i].dbCfg.minRows > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " minrows %d", g_Dbs.db[i].dbCfg.minRows);
      }
      if (g_Dbs.db[i].dbCfg.maxRows > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " maxrows %d", g_Dbs.db[i].dbCfg.maxRows);
      }
      if (g_Dbs.db[i].dbCfg.comp > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " comp %d", g_Dbs.db[i].dbCfg.comp);
      }
      if (g_Dbs.db[i].dbCfg.walLevel > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " wal %d", g_Dbs.db[i].dbCfg.walLevel);
      }
      if (g_Dbs.db[i].dbCfg.cacheLast > 0) {
        dataLen += snprintf(command + dataLen,
            BUFFER_SIZE - dataLen, " cachelast %d", g_Dbs.db[i].dbCfg.cacheLast);
      }
      if (g_Dbs.db[i].dbCfg.fsync > 0) {
        dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen,
                " fsync %d", g_Dbs.db[i].dbCfg.fsync);
      }
      if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", strlen("ms")))
              || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision,
                      "us", strlen("us")))) {
        dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen,
                " precision \'%s\';", g_Dbs.db[i].dbCfg.precision);
      }

      debugPrint("%s() %d command: %s\n", __func__, __LINE__, command);
      if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) {
        taos_close(taos);
        errorPrint( "\ncreate database %s failed!\n\n", g_Dbs.db[i].dbName);
        return -1;
      }
      printf("\ncreate database %s success!\n\n", g_Dbs.db[i].dbName);
2795 2796
    }

2797
    debugPrint("%s() LN%d supertbl count:%"PRIu64"\n",
2798
            __func__, __LINE__, g_Dbs.db[i].superTblCount);
2799 2800 2801

    int validStbCount = 0;

2802
    for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
2803 2804 2805 2806 2807 2808 2809
      sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName,
              g_Dbs.db[i].superTbls[j].sTblName);
      verbosePrint("%s() %d command: %s\n", __func__, __LINE__, command);

      ret = queryDbExec(taos, command, NO_INSERT_TYPE, true);

      if ((ret != 0) || (g_Dbs.db[i].drop)) {
2810
        ret = createSuperTable(taos, g_Dbs.db[i].dbName,
2811
                &g_Dbs.db[i].superTbls[j]);
2812

2813
        if (0 != ret) {
2814 2815
          errorPrint("create super table %d failed!\n\n", j);
          continue;
2816 2817 2818
        }
      }

2819
      ret = getSuperTableFromServer(taos, g_Dbs.db[i].dbName,
2820
                &g_Dbs.db[i].superTbls[j]);
2821 2822 2823
      if (0 != ret) {
        errorPrint("\nget super table %s.%s info failed!\n\n",
                g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName);
2824
        continue;
2825
      }
2826 2827

      validStbCount ++;
2828
    }
2829 2830

    g_Dbs.db[i].superTblCount = validStbCount;
2831 2832 2833 2834 2835 2836
  }

  taos_close(taos);
  return 0;
}

2837 2838
static void* createTable(void *sarg)
{
2839 2840
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
2841 2842 2843

  int64_t  lastPrintTime = taosGetTimestampMs();

2844
  int buff_len;
2845
  buff_len = BUFFER_SIZE / 8;
2846

2847
  char *buffer = calloc(buff_len, 1);
2848
  if (buffer == NULL) {
2849
    errorPrint("%s() LN%d, Memory allocated failed!\n", __func__, __LINE__);
2850 2851
    exit(-1);
  }
2852 2853 2854

  int len = 0;
  int batchNum = 0;
2855

2856
  verbosePrint("%s() LN%d: Creating table from %"PRIu64" to %"PRIu64"\n",
2857
          __func__, __LINE__,
2858
          pThreadInfo->start_table_from, pThreadInfo->end_table_to);
2859

2860
  for (uint64_t i = pThreadInfo->start_table_from;
2861
          i <= pThreadInfo->end_table_to; i++) {
2862
    if (0 == g_Dbs.use_metric) {
2863
      snprintf(buffer, buff_len,
2864
              "create table if not exists %s.%s%"PRIu64" %s;",
2865
              pThreadInfo->db_name,
2866
              g_args.tb_prefix, i,
2867
              pThreadInfo->cols);
2868
    } else {
2869 2870 2871
      if (superTblInfo == NULL) {
        errorPrint("%s() LN%d, use metric, but super table info is NULL\n",
                  __func__, __LINE__);
2872
        free(buffer);
2873 2874 2875 2876 2877 2878 2879 2880 2881 2882
        exit(-1);
      } else {
        if (0 == len) {
          batchNum = 0;
          memset(buffer, 0, buff_len);
          len += snprintf(buffer + len,
                  buff_len - len, "create table ");
        }
        char* tagsValBuf = NULL;
        if (0 == superTblInfo->tagSource) {
2883
          tagsValBuf = generateTagVaulesForStb(superTblInfo, i);
2884 2885 2886 2887 2888 2889 2890 2891 2892 2893
        } else {
          tagsValBuf = getTagValueFromTagSample(
                  superTblInfo,
                  i % superTblInfo->tagSampleCount);
        }
        if (NULL == tagsValBuf) {
          free(buffer);
          return NULL;
        }
        len += snprintf(buffer + len,
2894
                buff_len - len,
2895
                "if not exists %s.%s%"PRIu64" using %s.%s tags %s ",
2896 2897
                pThreadInfo->db_name, superTblInfo->childTblPrefix,
                i, pThreadInfo->db_name,
2898 2899 2900 2901
                superTblInfo->sTblName, tagsValBuf);
        free(tagsValBuf);
        batchNum++;
        if ((batchNum < superTblInfo->batchCreateTableNum)
2902
                && ((buff_len - len)
2903 2904 2905
                    >= (superTblInfo->lenOfTagOfOneRow + 256))) {
          continue;
        }
2906 2907 2908 2909
      }
    }

    len = 0;
2910
    verbosePrint("%s() LN%d %s\n", __func__, __LINE__, buffer);
2911
    if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)){
2912
      errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer);
2913
      free(buffer);
2914 2915 2916 2917 2918
      return NULL;
    }

    int64_t  currentPrintTime = taosGetTimestampMs();
    if (currentPrintTime - lastPrintTime > 30*1000) {
2919
      printf("thread[%d] already create %"PRIu64" - %"PRIu64" tables\n",
2920
              pThreadInfo->threadID, pThreadInfo->start_table_from, i);
2921 2922 2923
      lastPrintTime = currentPrintTime;
    }
  }
2924

2925
  if (0 != len) {
2926
    verbosePrint("%s() %d buffer: %s\n", __func__, __LINE__, buffer);
2927
    if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)) {
2928
      errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer);
2929
    }
2930
  }
2931

2932 2933 2934 2935
  free(buffer);
  return NULL;
}

2936
static int startMultiThreadCreateChildTable(
2937
        char* cols, int threads, uint64_t startFrom, int64_t ntables,
2938
        char* db_name, SSuperTable* superTblInfo) {
2939

2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951
  pthread_t *pids = malloc(threads * sizeof(pthread_t));
  threadInfo *infos = malloc(threads * sizeof(threadInfo));

  if ((NULL == pids) || (NULL == infos)) {
    printf("malloc failed\n");
    exit(-1);
  }

  if (threads < 1) {
    threads = 1;
  }

2952
  int64_t a = ntables / threads;
2953 2954 2955 2956 2957
  if (a < 1) {
    threads = ntables;
    a = 1;
  }

2958
  int64_t b = 0;
2959
  b = ntables % threads;
2960

2961
  for (int64_t i = 0; i < threads; i++) {
2962 2963
    threadInfo *t_info = infos + i;
    t_info->threadID = i;
H
Hui Li 已提交
2964
    tstrncpy(t_info->db_name, db_name, MAX_DB_NAME_SIZE);
2965
    t_info->superTblInfo = superTblInfo;
2966
    verbosePrint("%s() %d db_name: %s\n", __func__, __LINE__, db_name);
2967 2968 2969 2970 2971 2972
    t_info->taos = taos_connect(
            g_Dbs.host,
            g_Dbs.user,
            g_Dbs.password,
            db_name,
            g_Dbs.port);
2973
    if (t_info->taos == NULL) {
2974 2975
      errorPrint( "%s() LN%d, Failed to connect to TDengine, reason:%s\n",
         __func__, __LINE__, taos_errstr(NULL));
2976
      free(pids);
2977
      free(infos);
2978 2979
      return -1;
    }
2980 2981 2982 2983 2984

    t_info->start_table_from = startFrom;
    t_info->ntables = i<b?a+1:a;
    t_info->end_table_to = i < b ? startFrom + a : startFrom + a - 1;
    startFrom = t_info->end_table_to + 1;
2985
    t_info->use_metric = true;
2986
    t_info->cols = cols;
2987
    t_info->minDelay = UINT64_MAX;
2988 2989
    pthread_create(pids + i, NULL, createTable, t_info);
  }
2990

2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
  for (int i = 0; i < threads; i++) {
    pthread_join(pids[i], NULL);
  }

  for (int i = 0; i < threads; i++) {
    threadInfo *t_info = infos + i;
    taos_close(t_info->taos);
  }

  free(pids);
3001
  free(infos);
3002 3003

  return 0;
3004 3005
}

3006 3007 3008 3009
static void createChildTables() {
    char tblColsBuf[MAX_SQL_SIZE];
    int len;

3010
  for (int i = 0; i < g_Dbs.dbCount; i++) {
3011 3012 3013 3014 3015 3016 3017 3018
    if (g_Dbs.use_metric) {
      if (g_Dbs.db[i].superTblCount > 0) {
          // with super table
        for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
          if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable)
                || (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) {
            continue;
          }
3019

3020 3021
          verbosePrint("%s() LN%d: %s\n", __func__, __LINE__,
                  g_Dbs.db[i].superTbls[j].colsOfCreateChildTable);
3022
          uint64_t startFrom = 0;
3023 3024
          g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount;

3025
          verbosePrint("%s() LN%d: create %"PRId64" child tables from %"PRIu64"\n",
3026 3027 3028 3029 3030 3031 3032 3033
                  __func__, __LINE__, g_totalChildTables, startFrom);
          startMultiThreadCreateChildTable(
                g_Dbs.db[i].superTbls[j].colsOfCreateChildTable,
                g_Dbs.threadCountByCreateTbl,
                startFrom,
                g_Dbs.db[i].superTbls[j].childTblCount,
                g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j]));
        }
3034 3035
      }
    } else {
3036 3037
      // normal table
      len = snprintf(tblColsBuf, MAX_SQL_SIZE, "(TS TIMESTAMP");
3038
      for (int j = 0; j < g_args.num_of_CPR; j++) {
3039 3040 3041 3042
          if ((strncasecmp(g_args.datatype[j], "BINARY", strlen("BINARY")) == 0)
                  || (strncasecmp(g_args.datatype[j],
                      "NCHAR", strlen("NCHAR")) == 0)) {
              snprintf(tblColsBuf + len, MAX_SQL_SIZE - len,
3043
                      ", COL%d %s(%d)", j, g_args.datatype[j], g_args.len_of_binary);
3044 3045 3046 3047 3048 3049
          } else {
              snprintf(tblColsBuf + len, MAX_SQL_SIZE - len,
                      ", COL%d %s", j, g_args.datatype[j]);
          }
          len = strlen(tblColsBuf);
      }
3050

3051
      snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, ")");
3052

3053
      verbosePrint("%s() LN%d: dbName: %s num of tb: %"PRId64" schema: %s\n",
3054 3055 3056 3057 3058 3059 3060 3061 3062
              __func__, __LINE__,
              g_Dbs.db[i].dbName, g_args.num_of_tables, tblColsBuf);
      startMultiThreadCreateChildTable(
            tblColsBuf,
            g_Dbs.threadCountByCreateTbl,
            0,
            g_args.num_of_tables,
            g_Dbs.db[i].dbName,
            NULL);
3063
    }
3064 3065 3066 3067 3068 3069
  }
}

/*
  Read 10000 lines at most. If more than 10000 lines, continue to read after using
*/
3070
static int readTagFromCsvFileToMem(SSuperTable  * superTblInfo) {
3071 3072 3073
  size_t  n = 0;
  ssize_t readLen = 0;
  char *  line = NULL;
3074

3075 3076
  FILE *fp = fopen(superTblInfo->tagsFile, "r");
  if (fp == NULL) {
3077 3078
    printf("Failed to open tags file: %s, reason:%s\n",
            superTblInfo->tagsFile, strerror(errno));
3079 3080 3081 3082 3083 3084 3085
    return -1;
  }

  if (superTblInfo->tagDataBuf) {
    free(superTblInfo->tagDataBuf);
    superTblInfo->tagDataBuf = NULL;
  }
3086

3087 3088 3089 3090 3091 3092 3093 3094 3095
  int tagCount = 10000;
  int count = 0;
  char* tagDataBuf = calloc(1, superTblInfo->lenOfTagOfOneRow * tagCount);
  if (tagDataBuf == NULL) {
    printf("Failed to calloc, reason:%s\n", strerror(errno));
    fclose(fp);
    return -1;
  }

3096
  while((readLen = tgetline(&line, &n, fp)) != -1) {
3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108
    if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
      line[--readLen] = 0;
    }

    if (readLen == 0) {
      continue;
    }

    memcpy(tagDataBuf + count * superTblInfo->lenOfTagOfOneRow, line, readLen);
    count++;

    if (count >= tagCount - 1) {
3109 3110
      char *tmp = realloc(tagDataBuf,
              (size_t)tagCount*1.5*superTblInfo->lenOfTagOfOneRow);
3111 3112 3113
      if (tmp != NULL) {
        tagDataBuf = tmp;
        tagCount = (int)(tagCount*1.5);
3114 3115
        memset(tagDataBuf + count*superTblInfo->lenOfTagOfOneRow,
                0, (size_t)((tagCount-count)*superTblInfo->lenOfTagOfOneRow));
3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142
      } else {
        // exit, if allocate more memory failed
        printf("realloc fail for save tag val from %s\n", superTblInfo->tagsFile);
        tmfree(tagDataBuf);
        free(line);
        fclose(fp);
        return -1;
      }
    }
  }

  superTblInfo->tagDataBuf = tagDataBuf;
  superTblInfo->tagSampleCount = count;

  free(line);
  fclose(fp);
  return 0;
}

int readSampleFromJsonFileToMem(SSuperTable  * superTblInfo) {
  // TODO
  return 0;
}

/*
  Read 10000 lines at most. If more than 10000 lines, continue to read after using
*/
3143 3144
static int readSampleFromCsvFileToMem(
        SSuperTable* superTblInfo) {
3145 3146 3147 3148
  size_t  n = 0;
  ssize_t readLen = 0;
  char *  line = NULL;
  int getRows = 0;
3149

3150 3151
  FILE*  fp = fopen(superTblInfo->sampleFile, "r");
  if (fp == NULL) {
3152
      errorPrint( "Failed to open sample file: %s, reason:%s\n",
3153 3154 3155
              superTblInfo->sampleFile, strerror(errno));
      return -1;
  }
3156

3157
  assert(superTblInfo->sampleDataBuf);
3158 3159
  memset(superTblInfo->sampleDataBuf, 0,
          MAX_SAMPLES_ONCE_FROM_FILE * superTblInfo->lenOfOneRow);
3160
  while(1) {
3161
    readLen = tgetline(&line, &n, fp);
3162 3163
    if (-1 == readLen) {
      if(0 != fseek(fp, 0, SEEK_SET)) {
3164
        errorPrint( "Failed to fseek file: %s, reason:%s\n",
3165
                superTblInfo->sampleFile, strerror(errno));
3166
        fclose(fp);
3167 3168 3169 3170
        return -1;
      }
      continue;
    }
3171

3172 3173 3174 3175 3176 3177 3178 3179 3180
    if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
      line[--readLen] = 0;
    }

    if (readLen == 0) {
      continue;
    }

    if (readLen > superTblInfo->lenOfOneRow) {
3181
      printf("sample row len[%d] overflow define schema len[%"PRIu64"], so discard this row\n",
3182
              (int32_t)readLen, superTblInfo->lenOfOneRow);
3183 3184 3185
      continue;
    }

3186 3187
    memcpy(superTblInfo->sampleDataBuf + getRows * superTblInfo->lenOfOneRow,
          line, readLen);
3188 3189 3190 3191 3192 3193 3194
    getRows++;

    if (getRows == MAX_SAMPLES_ONCE_FROM_FILE) {
      break;
    }
  }

3195
  fclose(fp);
3196 3197 3198 3199
  tmfree(line);
  return 0;
}

3200 3201
static bool getColumnAndTagTypeFromInsertJsonFile(
        cJSON* stbInfo, SSuperTable* superTbls) {
3202
  bool  ret = false;
3203

3204
  // columns
3205 3206
  cJSON *columns = cJSON_GetObjectItem(stbInfo, "columns");
  if (columns && columns->type != cJSON_Array) {
3207
    printf("ERROR: failed to read json, columns not found\n");
3208 3209 3210 3211 3212 3213
    goto PARSE_OVER;
  } else if (NULL == columns) {
    superTbls->columnCount = 0;
    superTbls->tagCount    = 0;
    return true;
  }
3214

3215
  int columnSize = cJSON_GetArraySize(columns);
3216
  if ((columnSize + 1/* ts */) > MAX_COLUMN_COUNT) {
3217 3218
    errorPrint("%s() LN%d, failed to read json, column size overflow, max column size is %d\n",
            __func__, __LINE__, MAX_COLUMN_COUNT);
3219 3220 3221 3222 3223 3224
    goto PARSE_OVER;
  }

  int count = 1;
  int index = 0;
  StrColumn    columnCase;
3225

3226
  //superTbls->columnCount = columnSize;
3227 3228 3229 3230 3231 3232 3233
  for (int k = 0; k < columnSize; ++k) {
    cJSON* column = cJSON_GetArrayItem(columns, k);
    if (column == NULL) continue;

    count = 1;
    cJSON* countObj = cJSON_GetObjectItem(column, "count");
    if (countObj && countObj->type == cJSON_Number) {
3234
      count = countObj->valueint;
3235
    } else if (countObj && countObj->type != cJSON_Number) {
3236 3237
      errorPrint("%s() LN%d, failed to read json, column count not found\n",
          __func__, __LINE__);
3238 3239 3240 3241 3242
      goto PARSE_OVER;
    } else {
      count = 1;
    }

3243
    // column info
3244 3245
    memset(&columnCase, 0, sizeof(StrColumn));
    cJSON *dataType = cJSON_GetObjectItem(column, "type");
3246 3247 3248 3249
    if (!dataType || dataType->type != cJSON_String
        || dataType->valuestring == NULL) {
      errorPrint("%s() LN%d: failed to read json, column type not found\n",
          __func__, __LINE__);
3250 3251
      goto PARSE_OVER;
    }
3252 3253
    //tstrncpy(superTbls->columns[k].dataType, dataType->valuestring, MAX_TB_NAME_SIZE);
    tstrncpy(columnCase.dataType, dataType->valuestring, MAX_TB_NAME_SIZE);
3254

3255 3256
    cJSON* dataLen = cJSON_GetObjectItem(column, "len");
    if (dataLen && dataLen->type == cJSON_Number) {
3257
      columnCase.dataLen = dataLen->valueint;
3258
    } else if (dataLen && dataLen->type != cJSON_Number) {
3259 3260
      debugPrint("%s() LN%d: failed to read json, column len not found\n",
          __func__, __LINE__);
3261 3262 3263 3264
      goto PARSE_OVER;
    } else {
      columnCase.dataLen = 8;
    }
3265

3266
    for (int n = 0; n < count; ++n) {
3267 3268 3269
      tstrncpy(superTbls->columns[index].dataType,
              columnCase.dataType, MAX_TB_NAME_SIZE);
      superTbls->columns[index].dataLen = columnCase.dataLen;
3270 3271
      index++;
    }
3272
  }
3273

3274 3275
  if ((index + 1 /* ts */) > MAX_COLUMN_COUNT) {
    errorPrint("%s() LN%d, failed to read json, column size overflow, allowed max column size is %d\n",
3276 3277 3278 3279
            __func__, __LINE__, MAX_COLUMN_COUNT);
    goto PARSE_OVER;
  }

3280
  superTbls->columnCount = index;
3281

3282 3283
  count = 1;
  index = 0;
3284
  // tags
3285 3286
  cJSON *tags = cJSON_GetObjectItem(stbInfo, "tags");
  if (!tags || tags->type != cJSON_Array) {
3287 3288
    errorPrint("%s() LN%d, failed to read json, tags not found\n",
        __func__, __LINE__);
3289 3290
    goto PARSE_OVER;
  }
3291

3292 3293
  int tagSize = cJSON_GetArraySize(tags);
  if (tagSize > MAX_TAG_COUNT) {
3294 3295
    errorPrint("%s() LN%d, failed to read json, tags size overflow, max tag size is %d\n",
        __func__, __LINE__, MAX_TAG_COUNT);
3296 3297
    goto PARSE_OVER;
  }
3298 3299

  //superTbls->tagCount = tagSize;
3300 3301 3302
  for (int k = 0; k < tagSize; ++k) {
    cJSON* tag = cJSON_GetArrayItem(tags, k);
    if (tag == NULL) continue;
3303

3304 3305 3306
    count = 1;
    cJSON* countObj = cJSON_GetObjectItem(tag, "count");
    if (countObj && countObj->type == cJSON_Number) {
3307
      count = countObj->valueint;
3308
    } else if (countObj && countObj->type != cJSON_Number) {
3309
      printf("ERROR: failed to read json, column count not found\n");
3310 3311 3312 3313 3314
      goto PARSE_OVER;
    } else {
      count = 1;
    }

3315
    // column info
3316 3317
    memset(&columnCase, 0, sizeof(StrColumn));
    cJSON *dataType = cJSON_GetObjectItem(tag, "type");
3318 3319 3320 3321
    if (!dataType || dataType->type != cJSON_String
        || dataType->valuestring == NULL) {
      errorPrint("%s() LN%d, failed to read json, tag type not found\n",
          __func__, __LINE__);
3322 3323
      goto PARSE_OVER;
    }
3324
    tstrncpy(columnCase.dataType, dataType->valuestring, MAX_TB_NAME_SIZE);
3325

3326 3327
    cJSON* dataLen = cJSON_GetObjectItem(tag, "len");
    if (dataLen && dataLen->type == cJSON_Number) {
3328
      columnCase.dataLen = dataLen->valueint;
3329
    } else if (dataLen && dataLen->type != cJSON_Number) {
3330 3331
      errorPrint("%s() LN%d, failed to read json, column len not found\n",
          __func__, __LINE__);
3332 3333 3334
      goto PARSE_OVER;
    } else {
      columnCase.dataLen = 0;
3335 3336
    }

3337
    for (int n = 0; n < count; ++n) {
3338 3339
      tstrncpy(superTbls->tags[index].dataType, columnCase.dataType,
          MAX_TB_NAME_SIZE);
3340
      superTbls->tags[index].dataLen = columnCase.dataLen;
3341 3342
      index++;
    }
3343
  }
3344 3345

  if (index > MAX_TAG_COUNT) {
3346
    errorPrint("%s() LN%d, failed to read json, tags size overflow, allowed max tag count is %d\n",
3347 3348 3349 3350
        __func__, __LINE__, MAX_TAG_COUNT);
    goto PARSE_OVER;
  }

3351 3352
  superTbls->tagCount = index;

3353 3354 3355
  if ((superTbls->columnCount + superTbls->tagCount + 1 /* ts */) > MAX_COLUMN_COUNT) {
    errorPrint("%s() LN%d, columns + tags is more than allowed max columns count: %d\n",
        __func__, __LINE__, MAX_COLUMN_COUNT);
3356 3357
    goto PARSE_OVER;
  }
3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368
  ret = true;

PARSE_OVER:
  return ret;
}

static bool getMetaFromInsertJsonFile(cJSON* root) {
  bool  ret = false;

  cJSON* cfgdir = cJSON_GetObjectItem(root, "cfgdir");
  if (cfgdir && cfgdir->type == cJSON_String && cfgdir->valuestring != NULL) {
3369
    tstrncpy(g_Dbs.cfgDir, cfgdir->valuestring, MAX_FILE_NAME_LEN);
3370 3371 3372 3373
  }

  cJSON* host = cJSON_GetObjectItem(root, "host");
  if (host && host->type == cJSON_String && host->valuestring != NULL) {
3374
    tstrncpy(g_Dbs.host, host->valuestring, MAX_HOSTNAME_SIZE);
3375
  } else if (!host) {
3376
    tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
3377
  } else {
3378
    printf("ERROR: failed to read json, host not found\n");
3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390
    goto PARSE_OVER;
  }

  cJSON* port = cJSON_GetObjectItem(root, "port");
  if (port && port->type == cJSON_Number) {
    g_Dbs.port = port->valueint;
  } else if (!port) {
    g_Dbs.port = 6030;
  }

  cJSON* user = cJSON_GetObjectItem(root, "user");
  if (user && user->type == cJSON_String && user->valuestring != NULL) {
3391
    tstrncpy(g_Dbs.user, user->valuestring, MAX_USERNAME_SIZE);
3392
  } else if (!user) {
3393
    tstrncpy(g_Dbs.user, "root", MAX_USERNAME_SIZE);
3394 3395 3396 3397
  }

  cJSON* password = cJSON_GetObjectItem(root, "password");
  if (password && password->type == cJSON_String && password->valuestring != NULL) {
3398
    tstrncpy(g_Dbs.password, password->valuestring, MAX_PASSWORD_SIZE);
3399
  } else if (!password) {
3400
    tstrncpy(g_Dbs.password, "taosdata", MAX_PASSWORD_SIZE);
3401 3402 3403 3404
  }

  cJSON* resultfile = cJSON_GetObjectItem(root, "result_file");
  if (resultfile && resultfile->type == cJSON_String && resultfile->valuestring != NULL) {
3405
    tstrncpy(g_Dbs.resultFile, resultfile->valuestring, MAX_FILE_NAME_LEN);
3406
  } else if (!resultfile) {
3407
    tstrncpy(g_Dbs.resultFile, "./insert_res.txt", MAX_FILE_NAME_LEN);
3408 3409 3410 3411 3412 3413 3414 3415
  }

  cJSON* threads = cJSON_GetObjectItem(root, "thread_count");
  if (threads && threads->type == cJSON_Number) {
    g_Dbs.threadCount = threads->valueint;
  } else if (!threads) {
    g_Dbs.threadCount = 1;
  } else {
3416
    printf("ERROR: failed to read json, threads not found\n");
3417
    goto PARSE_OVER;
3418 3419
  }

3420 3421 3422 3423
  cJSON* threads2 = cJSON_GetObjectItem(root, "thread_count_create_tbl");
  if (threads2 && threads2->type == cJSON_Number) {
    g_Dbs.threadCountByCreateTbl = threads2->valueint;
  } else if (!threads2) {
3424
    g_Dbs.threadCountByCreateTbl = 1;
3425
  } else {
3426 3427
    errorPrint("%s() LN%d, failed to read json, threads2 not found\n",
            __func__, __LINE__);
3428
    goto PARSE_OVER;
3429
  }
3430

3431 3432
  cJSON* gInsertInterval = cJSON_GetObjectItem(root, "insert_interval");
  if (gInsertInterval && gInsertInterval->type == cJSON_Number) {
3433 3434 3435 3436 3437
    if (gInsertInterval->valueint <0) {
      errorPrint("%s() LN%d, failed to read json, insert interval input mistake\n",
            __func__, __LINE__);
      goto PARSE_OVER;
    }
3438 3439 3440 3441
    g_args.insert_interval = gInsertInterval->valueint;
  } else if (!gInsertInterval) {
    g_args.insert_interval = 0;
  } else {
3442 3443
    errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n",
        __func__, __LINE__);
3444 3445
    goto PARSE_OVER;
  }
3446

3447 3448
  cJSON* interlaceRows = cJSON_GetObjectItem(root, "interlace_rows");
  if (interlaceRows && interlaceRows->type == cJSON_Number) {
3449 3450 3451 3452 3453 3454
    if (interlaceRows->valueint < 0) {
      errorPrint("%s() LN%d, failed to read json, interlace_rows input mistake\n",
        __func__, __LINE__);
      goto PARSE_OVER;

    }
3455 3456
    g_args.interlace_rows = interlaceRows->valueint;
  } else if (!interlaceRows) {
3457
    g_args.interlace_rows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req
3458
  } else {
3459 3460
    errorPrint("%s() LN%d, failed to read json, interlace_rows input mistake\n",
        __func__, __LINE__);
3461
    goto PARSE_OVER;
3462
  }
3463

3464 3465
  cJSON* maxSqlLen = cJSON_GetObjectItem(root, "max_sql_len");
  if (maxSqlLen && maxSqlLen->type == cJSON_Number) {
3466 3467 3468 3469 3470
    if (maxSqlLen->valueint < 0) {
      errorPrint("%s() LN%d, failed to read json, max_sql_len input mistake\n",
        __func__, __LINE__);
      goto PARSE_OVER;
    }
3471 3472
    g_args.max_sql_len = maxSqlLen->valueint;
  } else if (!maxSqlLen) {
3473
    g_args.max_sql_len = (1024*1024);
3474
  } else {
3475 3476
    errorPrint("%s() LN%d, failed to read json, max_sql_len input mistake\n",
        __func__, __LINE__);
3477 3478 3479 3480 3481
    goto PARSE_OVER;
  }

  cJSON* numRecPerReq = cJSON_GetObjectItem(root, "num_of_records_per_req");
  if (numRecPerReq && numRecPerReq->type == cJSON_Number) {
3482
    if (numRecPerReq->valueint <= 0) {
3483 3484 3485
      errorPrint("%s() LN%d, failed to read json, num_of_records_per_req input mistake\n",
        __func__, __LINE__);
      goto PARSE_OVER;
3486
    } else if (numRecPerReq->valueint > MAX_RECORDS_PER_REQ) {
3487 3488 3489 3490 3491
      printf("NOTICE: number of records per request value %"PRIu64" > %d\n\n",
              numRecPerReq->valueint, MAX_RECORDS_PER_REQ);
      printf("        number of records per request value will be set to %d\n\n",
              MAX_RECORDS_PER_REQ);
      prompt();
3492
      numRecPerReq->valueint = MAX_RECORDS_PER_REQ;
3493
    }
3494 3495
    g_args.num_of_RPR = numRecPerReq->valueint;
  } else if (!numRecPerReq) {
3496
    g_args.num_of_RPR = MAX_RECORDS_PER_REQ;
3497
  } else {
3498 3499
    errorPrint("%s() LN%d, failed to read json, num_of_records_per_req not found\n",
        __func__, __LINE__);
3500 3501 3502
    goto PARSE_OVER;
  }

3503
  cJSON *answerPrompt = cJSON_GetObjectItem(root, "confirm_parameter_prompt"); // yes, no,
3504
  if (answerPrompt
3505 3506
          && answerPrompt->type == cJSON_String
          && answerPrompt->valuestring != NULL) {
3507 3508 3509 3510 3511 3512 3513 3514
    if (0 == strncasecmp(answerPrompt->valuestring, "yes", 3)) {
      g_args.answer_yes = false;
    } else if (0 == strncasecmp(answerPrompt->valuestring, "no", 2)) {
      g_args.answer_yes = true;
    } else {
      g_args.answer_yes = false;
    }
  } else if (!answerPrompt) {
3515
    g_args.answer_yes = true;   // default is no, mean answer_yes.
3516
  } else {
3517
    errorPrint("%s", "failed to read json, confirm_parameter_prompt input mistake\n");
3518
    goto PARSE_OVER;
3519
  }
3520

3521 3522 3523 3524 3525 3526 3527 3528 3529 3530
  // rows per table need be less than insert batch
  if (g_args.interlace_rows > g_args.num_of_RPR) {
      printf("NOTICE: interlace rows value %"PRIu64" > num_of_records_per_req %"PRIu64"\n\n",
              g_args.interlace_rows, g_args.num_of_RPR);
      printf("        interlace rows value will be set to num_of_records_per_req %"PRIu64"\n\n",
              g_args.num_of_RPR);
      prompt();
      g_args.interlace_rows = g_args.num_of_RPR;
  }

3531 3532
  cJSON* dbs = cJSON_GetObjectItem(root, "databases");
  if (!dbs || dbs->type != cJSON_Array) {
3533
    printf("ERROR: failed to read json, databases not found\n");
3534 3535 3536 3537 3538
    goto PARSE_OVER;
  }

  int dbSize = cJSON_GetArraySize(dbs);
  if (dbSize > MAX_DB_COUNT) {
3539
    errorPrint(
3540 3541
            "ERROR: failed to read json, databases size overflow, max database is %d\n",
            MAX_DB_COUNT);
3542 3543 3544 3545 3546 3547 3548 3549
    goto PARSE_OVER;
  }

  g_Dbs.dbCount = dbSize;
  for (int i = 0; i < dbSize; ++i) {
    cJSON* dbinfos = cJSON_GetArrayItem(dbs, i);
    if (dbinfos == NULL) continue;

3550
    // dbinfo
3551 3552
    cJSON *dbinfo = cJSON_GetObjectItem(dbinfos, "dbinfo");
    if (!dbinfo || dbinfo->type != cJSON_Object) {
3553
      printf("ERROR: failed to read json, dbinfo not found\n");
3554 3555
      goto PARSE_OVER;
    }
3556

3557 3558
    cJSON *dbName = cJSON_GetObjectItem(dbinfo, "name");
    if (!dbName || dbName->type != cJSON_String || dbName->valuestring == NULL) {
3559
      printf("ERROR: failed to read json, db name not found\n");
3560 3561
      goto PARSE_OVER;
    }
3562
    tstrncpy(g_Dbs.db[i].dbName, dbName->valuestring, MAX_DB_NAME_SIZE);
3563 3564 3565

    cJSON *drop = cJSON_GetObjectItem(dbinfo, "drop");
    if (drop && drop->type == cJSON_String && drop->valuestring != NULL) {
3566 3567
      if (0 == strncasecmp(drop->valuestring, "yes", strlen("yes"))) {
        g_Dbs.db[i].drop = true;
3568
      } else {
3569
        g_Dbs.db[i].drop = false;
3570
      }
3571
    } else if (!drop) {
3572
      g_Dbs.db[i].drop = g_args.drop_database;
3573
    } else {
3574 3575
      errorPrint("%s() LN%d, failed to read json, drop input mistake\n",
              __func__, __LINE__);
3576 3577 3578 3579
      goto PARSE_OVER;
    }

    cJSON *precision = cJSON_GetObjectItem(dbinfo, "precision");
3580 3581 3582 3583
    if (precision && precision->type == cJSON_String
            && precision->valuestring != NULL) {
      tstrncpy(g_Dbs.db[i].dbCfg.precision, precision->valuestring,
              MAX_DB_NAME_SIZE);
3584
    } else if (!precision) {
3585
      //tstrncpy(g_Dbs.db[i].dbCfg.precision, "ms", MAX_DB_NAME_SIZE);
3586 3587
      memset(g_Dbs.db[i].dbCfg.precision, 0, MAX_DB_NAME_SIZE);
    } else {
3588
      printf("ERROR: failed to read json, precision not found\n");
3589 3590 3591 3592 3593 3594 3595 3596 3597
      goto PARSE_OVER;
    }

    cJSON* update = cJSON_GetObjectItem(dbinfo, "update");
    if (update && update->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.update = update->valueint;
    } else if (!update) {
      g_Dbs.db[i].dbCfg.update = -1;
    } else {
3598
      printf("ERROR: failed to read json, update not found\n");
3599 3600 3601 3602 3603 3604 3605 3606 3607
      goto PARSE_OVER;
    }

    cJSON* replica = cJSON_GetObjectItem(dbinfo, "replica");
    if (replica && replica->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.replica = replica->valueint;
    } else if (!replica) {
      g_Dbs.db[i].dbCfg.replica = -1;
    } else {
3608
      printf("ERROR: failed to read json, replica not found\n");
3609 3610 3611 3612 3613 3614 3615 3616 3617
      goto PARSE_OVER;
    }

    cJSON* keep = cJSON_GetObjectItem(dbinfo, "keep");
    if (keep && keep->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.keep = keep->valueint;
    } else if (!keep) {
      g_Dbs.db[i].dbCfg.keep = -1;
    } else {
3618
     printf("ERROR: failed to read json, keep not found\n");
3619 3620
     goto PARSE_OVER;
    }
3621

3622 3623 3624 3625 3626 3627
    cJSON* days = cJSON_GetObjectItem(dbinfo, "days");
    if (days && days->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.days = days->valueint;
    } else if (!days) {
      g_Dbs.db[i].dbCfg.days = -1;
    } else {
3628
     printf("ERROR: failed to read json, days not found\n");
3629 3630
     goto PARSE_OVER;
    }
3631

3632 3633 3634 3635 3636 3637
    cJSON* cache = cJSON_GetObjectItem(dbinfo, "cache");
    if (cache && cache->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.cache = cache->valueint;
    } else if (!cache) {
      g_Dbs.db[i].dbCfg.cache = -1;
    } else {
3638
     printf("ERROR: failed to read json, cache not found\n");
3639 3640
     goto PARSE_OVER;
    }
3641

3642 3643 3644 3645 3646 3647
    cJSON* blocks= cJSON_GetObjectItem(dbinfo, "blocks");
    if (blocks && blocks->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.blocks = blocks->valueint;
    } else if (!blocks) {
      g_Dbs.db[i].dbCfg.blocks = -1;
    } else {
3648
     printf("ERROR: failed to read json, block not found\n");
3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665
     goto PARSE_OVER;
    }

    //cJSON* maxtablesPerVnode= cJSON_GetObjectItem(dbinfo, "maxtablesPerVnode");
    //if (maxtablesPerVnode && maxtablesPerVnode->type == cJSON_Number) {
    //  g_Dbs.db[i].dbCfg.maxtablesPerVnode = maxtablesPerVnode->valueint;
    //} else if (!maxtablesPerVnode) {
    //  g_Dbs.db[i].dbCfg.maxtablesPerVnode = TSDB_DEFAULT_TABLES;
    //} else {
    // printf("failed to read json, maxtablesPerVnode not found");
    // goto PARSE_OVER;
    //}

    cJSON* minRows= cJSON_GetObjectItem(dbinfo, "minRows");
    if (minRows && minRows->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.minRows = minRows->valueint;
    } else if (!minRows) {
3666
      g_Dbs.db[i].dbCfg.minRows = 0;    // 0 means default
3667
    } else {
3668
     printf("ERROR: failed to read json, minRows not found\n");
3669 3670 3671 3672 3673 3674 3675
     goto PARSE_OVER;
    }

    cJSON* maxRows= cJSON_GetObjectItem(dbinfo, "maxRows");
    if (maxRows && maxRows->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.maxRows = maxRows->valueint;
    } else if (!maxRows) {
3676
      g_Dbs.db[i].dbCfg.maxRows = 0;    // 0 means default
3677
    } else {
3678
     printf("ERROR: failed to read json, maxRows not found\n");
3679 3680 3681 3682 3683 3684 3685 3686 3687
     goto PARSE_OVER;
    }

    cJSON* comp= cJSON_GetObjectItem(dbinfo, "comp");
    if (comp && comp->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.comp = comp->valueint;
    } else if (!comp) {
      g_Dbs.db[i].dbCfg.comp = -1;
    } else {
3688
     printf("ERROR: failed to read json, comp not found\n");
3689 3690 3691 3692 3693 3694 3695 3696 3697
     goto PARSE_OVER;
    }

    cJSON* walLevel= cJSON_GetObjectItem(dbinfo, "walLevel");
    if (walLevel && walLevel->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.walLevel = walLevel->valueint;
    } else if (!walLevel) {
      g_Dbs.db[i].dbCfg.walLevel = -1;
    } else {
3698
     printf("ERROR: failed to read json, walLevel not found\n");
3699 3700 3701
     goto PARSE_OVER;
    }

3702 3703 3704 3705 3706 3707
    cJSON* cacheLast= cJSON_GetObjectItem(dbinfo, "cachelast");
    if (cacheLast && cacheLast->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.cacheLast = cacheLast->valueint;
    } else if (!cacheLast) {
      g_Dbs.db[i].dbCfg.cacheLast = -1;
    } else {
3708
     printf("ERROR: failed to read json, cacheLast not found\n");
3709 3710 3711
     goto PARSE_OVER;
    }

3712 3713 3714 3715
    cJSON* quorum= cJSON_GetObjectItem(dbinfo, "quorum");
    if (quorum && quorum->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.quorum = quorum->valueint;
    } else if (!quorum) {
3716
      g_Dbs.db[i].dbCfg.quorum = 1;
3717
    } else {
3718
     printf("failed to read json, quorum input mistake");
3719 3720 3721 3722 3723 3724 3725 3726 3727
     goto PARSE_OVER;
    }

    cJSON* fsync= cJSON_GetObjectItem(dbinfo, "fsync");
    if (fsync && fsync->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.fsync = fsync->valueint;
    } else if (!fsync) {
      g_Dbs.db[i].dbCfg.fsync = -1;
    } else {
3728 3729 3730
      errorPrint("%s() LN%d, failed to read json, fsync input mistake\n",
              __func__, __LINE__);
      goto PARSE_OVER;
3731
    }
3732

3733
    // super_talbes
3734 3735
    cJSON *stables = cJSON_GetObjectItem(dbinfos, "super_tables");
    if (!stables || stables->type != cJSON_Array) {
3736 3737
      errorPrint("%s() LN%d, failed to read json, super_tables not found\n",
              __func__, __LINE__);
3738
      goto PARSE_OVER;
3739 3740
    }

3741 3742
    int stbSize = cJSON_GetArraySize(stables);
    if (stbSize > MAX_SUPER_TABLE_COUNT) {
3743
      errorPrint(
3744 3745
              "%s() LN%d, failed to read json, supertable size overflow, max supertable is %d\n",
              __func__, __LINE__, MAX_SUPER_TABLE_COUNT);
3746 3747 3748 3749 3750 3751 3752
      goto PARSE_OVER;
    }

    g_Dbs.db[i].superTblCount = stbSize;
    for (int j = 0; j < stbSize; ++j) {
      cJSON* stbInfo = cJSON_GetArrayItem(stables, j);
      if (stbInfo == NULL) continue;
3753 3754

      // dbinfo
3755 3756
      cJSON *stbName = cJSON_GetObjectItem(stbInfo, "name");
      if (!stbName || stbName->type != cJSON_String || stbName->valuestring == NULL) {
3757 3758
        errorPrint("%s() LN%d, failed to read json, stb name not found\n",
                __func__, __LINE__);
3759 3760
        goto PARSE_OVER;
      }
3761
      tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring, MAX_TB_NAME_SIZE);
3762

3763 3764
      cJSON *prefix = cJSON_GetObjectItem(stbInfo, "childtable_prefix");
      if (!prefix || prefix->type != cJSON_String || prefix->valuestring == NULL) {
3765
        printf("ERROR: failed to read json, childtable_prefix not found\n");
3766 3767
        goto PARSE_OVER;
      }
3768
      tstrncpy(g_Dbs.db[i].superTbls[j].childTblPrefix, prefix->valuestring, MAX_DB_NAME_SIZE);
3769 3770

      cJSON *autoCreateTbl = cJSON_GetObjectItem(stbInfo, "auto_create_table"); // yes, no, null
3771 3772 3773
      if (autoCreateTbl
              && autoCreateTbl->type == cJSON_String
              && autoCreateTbl->valuestring != NULL) {
3774 3775 3776 3777 3778 3779 3780 3781 3782 3783
        if (0 == strncasecmp(autoCreateTbl->valuestring, "yes", 3)) {
          g_Dbs.db[i].superTbls[j].autoCreateTable = AUTO_CREATE_SUBTBL;
        } else if (0 == strncasecmp(autoCreateTbl->valuestring, "no", 2)) {
          g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL;
        } else {
          g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL;
        }
      } else if (!autoCreateTbl) {
        g_Dbs.db[i].superTbls[j].autoCreateTable = PRE_CREATE_SUBTBL;
      } else {
3784
        printf("ERROR: failed to read json, auto_create_table not found\n");
3785 3786
        goto PARSE_OVER;
      }
3787

3788 3789 3790 3791
      cJSON* batchCreateTbl = cJSON_GetObjectItem(stbInfo, "batch_create_tbl_num");
      if (batchCreateTbl && batchCreateTbl->type == cJSON_Number) {
        g_Dbs.db[i].superTbls[j].batchCreateTableNum = batchCreateTbl->valueint;
      } else if (!batchCreateTbl) {
3792
        g_Dbs.db[i].superTbls[j].batchCreateTableNum = 1000;
3793
      } else {
3794
        printf("ERROR: failed to read json, batch_create_tbl_num not found\n");
3795
        goto PARSE_OVER;
3796
      }
3797 3798

      cJSON *childTblExists = cJSON_GetObjectItem(stbInfo, "child_table_exists"); // yes, no
3799 3800 3801
      if (childTblExists
              && childTblExists->type == cJSON_String
              && childTblExists->valuestring != NULL) {
3802 3803
        if ((0 == strncasecmp(childTblExists->valuestring, "yes", 3))
            && (g_Dbs.db[i].drop == false)) {
3804
          g_Dbs.db[i].superTbls[j].childTblExists = TBL_ALREADY_EXISTS;
3805 3806
        } else if ((0 == strncasecmp(childTblExists->valuestring, "no", 2)
              || (g_Dbs.db[i].drop == true))) {
3807 3808 3809 3810 3811 3812 3813
          g_Dbs.db[i].superTbls[j].childTblExists = TBL_NO_EXISTS;
        } else {
          g_Dbs.db[i].superTbls[j].childTblExists = TBL_NO_EXISTS;
        }
      } else if (!childTblExists) {
        g_Dbs.db[i].superTbls[j].childTblExists = TBL_NO_EXISTS;
      } else {
3814 3815
        errorPrint("%s() LN%d, failed to read json, child_table_exists not found\n",
                __func__, __LINE__);
3816 3817
        goto PARSE_OVER;
      }
3818

3819 3820
      cJSON* count = cJSON_GetObjectItem(stbInfo, "childtable_count");
      if (!count || count->type != cJSON_Number || 0 >= count->valueint) {
3821
        errorPrint("%s() LN%d, failed to read json, childtable_count input mistake\n",
3822
                __func__, __LINE__);
3823 3824 3825 3826 3827
        goto PARSE_OVER;
      }
      g_Dbs.db[i].superTbls[j].childTblCount = count->valueint;

      cJSON *dataSource = cJSON_GetObjectItem(stbInfo, "data_source");
3828 3829 3830 3831
      if (dataSource && dataSource->type == cJSON_String
              && dataSource->valuestring != NULL) {
        tstrncpy(g_Dbs.db[i].superTbls[j].dataSource,
                dataSource->valuestring, MAX_DB_NAME_SIZE);
3832
      } else if (!dataSource) {
3833
        tstrncpy(g_Dbs.db[i].superTbls[j].dataSource, "rand", MAX_DB_NAME_SIZE);
3834
      } else {
3835 3836
        errorPrint("%s() LN%d, failed to read json, data_source not found\n",
            __func__, __LINE__);
3837 3838 3839
        goto PARSE_OVER;
      }

3840
      cJSON *insertMode = cJSON_GetObjectItem(stbInfo, "insert_mode"); // taosc , rest
3841 3842 3843 3844
      if (insertMode && insertMode->type == cJSON_String
              && insertMode->valuestring != NULL) {
        tstrncpy(g_Dbs.db[i].superTbls[j].insertMode,
                insertMode->valuestring, MAX_DB_NAME_SIZE);
3845
      } else if (!insertMode) {
3846
        tstrncpy(g_Dbs.db[i].superTbls[j].insertMode, "taosc", MAX_DB_NAME_SIZE);
3847
      } else {
3848
        printf("ERROR: failed to read json, insert_mode not found\n");
3849 3850 3851
        goto PARSE_OVER;
      }

3852
      cJSON* childTbl_limit = cJSON_GetObjectItem(stbInfo, "childtable_limit");
3853 3854
      if ((childTbl_limit) && (g_Dbs.db[i].drop != true)
          && (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) {
3855 3856 3857 3858 3859 3860
        if (childTbl_limit->type != cJSON_Number) {
            printf("ERROR: failed to read json, childtable_limit\n");
            goto PARSE_OVER;
        }
        g_Dbs.db[i].superTbls[j].childTblLimit = childTbl_limit->valueint;
      } else {
3861
        g_Dbs.db[i].superTbls[j].childTblLimit = -1;    // select ... limit -1 means all query result, drop = yes mean all table need recreate, limit value is invalid.
3862 3863 3864
      }

      cJSON* childTbl_offset = cJSON_GetObjectItem(stbInfo, "childtable_offset");
3865 3866
      if ((childTbl_offset) && (g_Dbs.db[i].drop != true)
          && (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) {
3867 3868 3869 3870 3871 3872 3873 3874 3875
        if (childTbl_offset->type != cJSON_Number || 0 > childTbl_offset->valueint) {
            printf("ERROR: failed to read json, childtable_offset\n");
            goto PARSE_OVER;
        }
        g_Dbs.db[i].superTbls[j].childTblOffset = childTbl_offset->valueint;
      } else {
        g_Dbs.db[i].superTbls[j].childTblOffset = 0;
      }

3876 3877
      cJSON *ts = cJSON_GetObjectItem(stbInfo, "start_timestamp");
      if (ts && ts->type == cJSON_String && ts->valuestring != NULL) {
3878 3879
        tstrncpy(g_Dbs.db[i].superTbls[j].startTimestamp,
                ts->valuestring, MAX_DB_NAME_SIZE);
3880
      } else if (!ts) {
3881 3882
        tstrncpy(g_Dbs.db[i].superTbls[j].startTimestamp,
                "now", MAX_DB_NAME_SIZE);
3883
      } else {
3884
        printf("ERROR: failed to read json, start_timestamp not found\n");
3885 3886
        goto PARSE_OVER;
      }
3887

3888 3889 3890 3891
      cJSON* timestampStep = cJSON_GetObjectItem(stbInfo, "timestamp_step");
      if (timestampStep && timestampStep->type == cJSON_Number) {
        g_Dbs.db[i].superTbls[j].timeStampStep = timestampStep->valueint;
      } else if (!timestampStep) {
3892
        g_Dbs.db[i].superTbls[j].timeStampStep = DEFAULT_TIMESTAMP_STEP;
3893
      } else {
3894
        printf("ERROR: failed to read json, timestamp_step not found\n");
3895 3896 3897 3898
        goto PARSE_OVER;
      }

      cJSON *sampleFormat = cJSON_GetObjectItem(stbInfo, "sample_format");
3899 3900
      if (sampleFormat && sampleFormat->type
              == cJSON_String && sampleFormat->valuestring != NULL) {
3901 3902
        tstrncpy(g_Dbs.db[i].superTbls[j].sampleFormat,
                sampleFormat->valuestring, MAX_DB_NAME_SIZE);
3903
      } else if (!sampleFormat) {
3904
        tstrncpy(g_Dbs.db[i].superTbls[j].sampleFormat, "csv", MAX_DB_NAME_SIZE);
3905
      } else {
3906
        printf("ERROR: failed to read json, sample_format not found\n");
3907
        goto PARSE_OVER;
3908
      }
3909

3910
      cJSON *sampleFile = cJSON_GetObjectItem(stbInfo, "sample_file");
3911 3912
      if (sampleFile && sampleFile->type == cJSON_String
          && sampleFile->valuestring != NULL) {
3913 3914
        tstrncpy(g_Dbs.db[i].superTbls[j].sampleFile,
                sampleFile->valuestring, MAX_FILE_NAME_LEN);
3915 3916 3917
      } else if (!sampleFile) {
        memset(g_Dbs.db[i].superTbls[j].sampleFile, 0, MAX_FILE_NAME_LEN);
      } else {
3918
        printf("ERROR: failed to read json, sample_file not found\n");
3919
        goto PARSE_OVER;
3920
      }
3921

3922 3923
      cJSON *tagsFile = cJSON_GetObjectItem(stbInfo, "tags_file");
      if (tagsFile && tagsFile->type == cJSON_String && tagsFile->valuestring != NULL) {
3924 3925
        tstrncpy(g_Dbs.db[i].superTbls[j].tagsFile,
                tagsFile->valuestring, MAX_FILE_NAME_LEN);
3926 3927 3928 3929 3930 3931 3932 3933 3934
        if (0 == g_Dbs.db[i].superTbls[j].tagsFile[0]) {
          g_Dbs.db[i].superTbls[j].tagSource = 0;
        } else {
          g_Dbs.db[i].superTbls[j].tagSource = 1;
        }
      } else if (!tagsFile) {
        memset(g_Dbs.db[i].superTbls[j].tagsFile, 0, MAX_FILE_NAME_LEN);
        g_Dbs.db[i].superTbls[j].tagSource = 0;
      } else {
3935
        printf("ERROR: failed to read json, tags_file not found\n");
3936 3937
        goto PARSE_OVER;
      }
3938

3939 3940 3941 3942 3943
      cJSON* maxSqlLen = cJSON_GetObjectItem(stbInfo, "max_sql_len");
      if (maxSqlLen && maxSqlLen->type == cJSON_Number) {
        int32_t len = maxSqlLen->valueint;
        if (len > TSDB_MAX_ALLOWED_SQL_LEN) {
          len = TSDB_MAX_ALLOWED_SQL_LEN;
3944 3945
        } else if (len < 5) {
          len = 5;
3946
        }
3947 3948
        g_Dbs.db[i].superTbls[j].maxSqlLen = len;
      } else if (!maxSqlLen) {
3949
        g_Dbs.db[i].superTbls[j].maxSqlLen = g_args.max_sql_len;
3950
      } else {
3951 3952
        errorPrint("%s() LN%d, failed to read json, maxSqlLen input mistake\n",
            __func__, __LINE__);
3953
        goto PARSE_OVER;
3954
      }
3955
/*
3956 3957 3958 3959 3960
      cJSON *multiThreadWriteOneTbl =
          cJSON_GetObjectItem(stbInfo, "multi_thread_write_one_tbl"); // no , yes
      if (multiThreadWriteOneTbl
              && multiThreadWriteOneTbl->type == cJSON_String
              && multiThreadWriteOneTbl->valuestring != NULL) {
3961 3962 3963 3964
        if (0 == strncasecmp(multiThreadWriteOneTbl->valuestring, "yes", 3)) {
          g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl = 1;
        } else {
          g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl = 0;
3965
        }
3966 3967 3968
      } else if (!multiThreadWriteOneTbl) {
        g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl = 0;
      } else {
3969
        printf("ERROR: failed to read json, multiThreadWriteOneTbl not found\n");
3970 3971
        goto PARSE_OVER;
      }
3972
*/
3973 3974
      cJSON* interlaceRows = cJSON_GetObjectItem(stbInfo, "interlace_rows");
      if (interlaceRows && interlaceRows->type == cJSON_Number) {
3975 3976 3977 3978 3979
        if (interlaceRows->valueint < 0) {
          errorPrint("%s() LN%d, failed to read json, interlace rows input mistake\n",
            __func__, __LINE__);
          goto PARSE_OVER;
        }
3980
        g_Dbs.db[i].superTbls[j].interlaceRows = interlaceRows->valueint;
3981 3982
        // rows per table need be less than insert batch
        if (g_Dbs.db[i].superTbls[j].interlaceRows > g_args.num_of_RPR) {
3983
          printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %"PRIu64" > num_of_records_per_req %"PRIu64"\n\n",
3984
                  i, j, g_Dbs.db[i].superTbls[j].interlaceRows, g_args.num_of_RPR);
3985
          printf("        interlace rows value will be set to num_of_records_per_req %"PRIu64"\n\n",
3986
                  g_args.num_of_RPR);
3987
          prompt();
3988 3989
          g_Dbs.db[i].superTbls[j].interlaceRows = g_args.num_of_RPR;
        }
3990 3991
      } else if (!interlaceRows) {
        g_Dbs.db[i].superTbls[j].interlaceRows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req
3992
      } else {
3993 3994 3995
        errorPrint(
                "%s() LN%d, failed to read json, interlace rows input mistake\n",
                __func__, __LINE__);
3996
        goto PARSE_OVER;
3997
      }
3998 3999 4000

      cJSON* disorderRatio = cJSON_GetObjectItem(stbInfo, "disorder_ratio");
      if (disorderRatio && disorderRatio->type == cJSON_Number) {
4001 4002 4003 4004 4005 4006
        if (disorderRatio->valueint > 50)
          disorderRatio->valueint = 50;

        if (disorderRatio->valueint < 0)
          disorderRatio->valueint = 0;

4007 4008 4009 4010
        g_Dbs.db[i].superTbls[j].disorderRatio = disorderRatio->valueint;
      } else if (!disorderRatio) {
        g_Dbs.db[i].superTbls[j].disorderRatio = 0;
      } else {
4011
        printf("ERROR: failed to read json, disorderRatio not found\n");
4012
        goto PARSE_OVER;
4013
      }
4014 4015 4016 4017 4018 4019 4020

      cJSON* disorderRange = cJSON_GetObjectItem(stbInfo, "disorder_range");
      if (disorderRange && disorderRange->type == cJSON_Number) {
        g_Dbs.db[i].superTbls[j].disorderRange = disorderRange->valueint;
      } else if (!disorderRange) {
        g_Dbs.db[i].superTbls[j].disorderRange = 1000;
      } else {
4021
        printf("ERROR: failed to read json, disorderRange not found\n");
4022 4023
        goto PARSE_OVER;
      }
4024

4025 4026
      cJSON* insertRows = cJSON_GetObjectItem(stbInfo, "insert_rows");
      if (insertRows && insertRows->type == cJSON_Number) {
4027 4028 4029 4030 4031
        if (insertRows->valueint < 0) {
          errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
                __func__, __LINE__);
          goto PARSE_OVER;
        }
4032 4033 4034 4035
        g_Dbs.db[i].superTbls[j].insertRows = insertRows->valueint;
      } else if (!insertRows) {
        g_Dbs.db[i].superTbls[j].insertRows = 0x7FFFFFFFFFFFFFFF;
      } else {
4036 4037
        errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
                __func__, __LINE__);
4038 4039 4040 4041 4042 4043
        goto PARSE_OVER;
      }

      cJSON* insertInterval = cJSON_GetObjectItem(stbInfo, "insert_interval");
      if (insertInterval && insertInterval->type == cJSON_Number) {
        g_Dbs.db[i].superTbls[j].insertInterval = insertInterval->valueint;
4044 4045 4046 4047 4048
        if (insertInterval->valueint < 0) {
          errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n",
                __func__, __LINE__);
          goto PARSE_OVER;
        }
4049
      } else if (!insertInterval) {
4050
        verbosePrint("%s() LN%d: stable insert interval be overrided by global %"PRIu64".\n",
4051 4052 4053
                __func__, __LINE__, g_args.insert_interval);
        g_Dbs.db[i].superTbls[j].insertInterval = g_args.insert_interval;
      } else {
4054 4055
        errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n",
                __func__, __LINE__);
4056 4057 4058
        goto PARSE_OVER;
      }

4059 4060
      int retVal = getColumnAndTagTypeFromInsertJsonFile(
              stbInfo, &g_Dbs.db[i].superTbls[j]);
4061 4062
      if (false == retVal) {
        goto PARSE_OVER;
4063 4064
      }
    }
4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077
  }

  ret = true;

PARSE_OVER:
  return ret;
}

static bool getMetaFromQueryJsonFile(cJSON* root) {
  bool  ret = false;

  cJSON* cfgdir = cJSON_GetObjectItem(root, "cfgdir");
  if (cfgdir && cfgdir->type == cJSON_String && cfgdir->valuestring != NULL) {
4078
    tstrncpy(g_queryInfo.cfgDir, cfgdir->valuestring, MAX_FILE_NAME_LEN);
4079 4080 4081 4082
  }

  cJSON* host = cJSON_GetObjectItem(root, "host");
  if (host && host->type == cJSON_String && host->valuestring != NULL) {
4083
    tstrncpy(g_queryInfo.host, host->valuestring, MAX_HOSTNAME_SIZE);
4084
  } else if (!host) {
4085
    tstrncpy(g_queryInfo.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
4086
  } else {
4087
    printf("ERROR: failed to read json, host not found\n");
4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099
    goto PARSE_OVER;
  }

  cJSON* port = cJSON_GetObjectItem(root, "port");
  if (port && port->type == cJSON_Number) {
    g_queryInfo.port = port->valueint;
  } else if (!port) {
    g_queryInfo.port = 6030;
  }

  cJSON* user = cJSON_GetObjectItem(root, "user");
  if (user && user->type == cJSON_String && user->valuestring != NULL) {
4100
    tstrncpy(g_queryInfo.user, user->valuestring, MAX_USERNAME_SIZE);
4101
  } else if (!user) {
4102
    tstrncpy(g_queryInfo.user, "root", MAX_USERNAME_SIZE); ;
4103 4104 4105 4106
  }

  cJSON* password = cJSON_GetObjectItem(root, "password");
  if (password && password->type == cJSON_String && password->valuestring != NULL) {
4107
    tstrncpy(g_queryInfo.password, password->valuestring, MAX_PASSWORD_SIZE);
4108
  } else if (!password) {
4109
    tstrncpy(g_queryInfo.password, "taosdata", MAX_PASSWORD_SIZE);;
4110
  }
H
hzcheng 已提交
4111

4112
  cJSON *answerPrompt = cJSON_GetObjectItem(root, "confirm_parameter_prompt"); // yes, no,
4113 4114
  if (answerPrompt && answerPrompt->type == cJSON_String
          && answerPrompt->valuestring != NULL) {
4115 4116 4117 4118
    if (0 == strncasecmp(answerPrompt->valuestring, "yes", 3)) {
      g_args.answer_yes = false;
    } else if (0 == strncasecmp(answerPrompt->valuestring, "no", 2)) {
      g_args.answer_yes = true;
H
hzcheng 已提交
4119
    } else {
4120
      g_args.answer_yes = false;
H
hzcheng 已提交
4121
    }
4122 4123 4124
  } else if (!answerPrompt) {
    g_args.answer_yes = false;
  } else {
4125
    printf("ERROR: failed to read json, confirm_parameter_prompt not found\n");
4126
    goto PARSE_OVER;
4127
  }
4128

4129 4130
  cJSON* gQueryTimes = cJSON_GetObjectItem(root, "query_times");
  if (gQueryTimes && gQueryTimes->type == cJSON_Number) {
4131
    if (gQueryTimes->valueint <= 0) {
4132 4133
      errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
        __func__, __LINE__);
4134 4135
      goto PARSE_OVER;
    }
4136 4137 4138 4139
    g_args.query_times = gQueryTimes->valueint;
  } else if (!gQueryTimes) {
    g_args.query_times = 1;
  } else {
4140 4141
    errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
        __func__, __LINE__);
4142 4143 4144
    goto PARSE_OVER;
  }

4145 4146
  cJSON* dbs = cJSON_GetObjectItem(root, "databases");
  if (dbs && dbs->type == cJSON_String && dbs->valuestring != NULL) {
4147
    tstrncpy(g_queryInfo.dbName, dbs->valuestring, MAX_DB_NAME_SIZE);
4148
  } else if (!dbs) {
4149
    printf("ERROR: failed to read json, databases not found\n");
4150
    goto PARSE_OVER;
H
hzcheng 已提交
4151
  }
4152 4153 4154

  cJSON* queryMode = cJSON_GetObjectItem(root, "query_mode");
  if (queryMode && queryMode->type == cJSON_String && queryMode->valuestring != NULL) {
4155
    tstrncpy(g_queryInfo.queryMode, queryMode->valuestring, MAX_TB_NAME_SIZE);
4156
  } else if (!queryMode) {
4157
    tstrncpy(g_queryInfo.queryMode, "taosc", MAX_TB_NAME_SIZE);
4158
  } else {
4159
    printf("ERROR: failed to read json, query_mode not found\n");
4160
    goto PARSE_OVER;
H
hzcheng 已提交
4161
  }
4162

4163
  // specified_table_query
4164 4165
  cJSON *specifiedQuery = cJSON_GetObjectItem(root, "specified_table_query");
  if (!specifiedQuery) {
4166
    g_queryInfo.specifiedQueryInfo.concurrent = 1;
4167 4168
    g_queryInfo.specifiedQueryInfo.sqlCount = 0;
  } else if (specifiedQuery->type != cJSON_Object) {
4169
    printf("ERROR: failed to read json, super_table_query not found\n");
4170
    goto PARSE_OVER;
4171
  } else {
4172 4173 4174 4175 4176
    cJSON* queryInterval = cJSON_GetObjectItem(specifiedQuery, "query_interval");
    if (queryInterval && queryInterval->type == cJSON_Number) {
      g_queryInfo.specifiedQueryInfo.queryInterval = queryInterval->valueint;
    } else if (!queryInterval) {
      g_queryInfo.specifiedQueryInfo.queryInterval = 0;
4177 4178
    }

4179 4180
    cJSON* specifiedQueryTimes = cJSON_GetObjectItem(specifiedQuery,
        "query_times");
4181
    if (specifiedQueryTimes && specifiedQueryTimes->type == cJSON_Number) {
4182
      if (specifiedQueryTimes->valueint <= 0) {
4183 4184
        errorPrint(
                "%s() LN%d, failed to read json, query_times: %"PRId64", need be a valid (>0) number\n",
4185
          __func__, __LINE__, specifiedQueryTimes->valueint);
4186 4187 4188
        goto PARSE_OVER;

      }
4189 4190 4191 4192
      g_queryInfo.specifiedQueryInfo.queryTimes = specifiedQueryTimes->valueint;
    } else if (!specifiedQueryTimes) {
      g_queryInfo.specifiedQueryInfo.queryTimes = g_args.query_times;
    } else {
4193 4194
      errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
          __func__, __LINE__);
4195
      goto PARSE_OVER;
4196
    }
4197

4198
    cJSON* concurrent = cJSON_GetObjectItem(specifiedQuery, "concurrent");
4199
    if (concurrent && concurrent->type == cJSON_Number) {
4200
      if (concurrent->valueint <= 0) {
4201 4202
        errorPrint(
                "%s() LN%d, query sqlCount %"PRIu64" or concurrent %"PRIu64" is not correct.\n",
4203 4204
              __func__, __LINE__,
              g_queryInfo.specifiedQueryInfo.sqlCount,
4205 4206 4207
              g_queryInfo.specifiedQueryInfo.concurrent);
        goto PARSE_OVER;
      }
4208
      g_queryInfo.specifiedQueryInfo.concurrent = concurrent->valueint;
4209
    } else if (!concurrent) {
4210
      g_queryInfo.specifiedQueryInfo.concurrent = 1;
4211
    }
4212

4213 4214 4215 4216 4217 4218 4219
    cJSON* specifiedAsyncMode = cJSON_GetObjectItem(specifiedQuery, "mode");
    if (specifiedAsyncMode && specifiedAsyncMode->type == cJSON_String
        && specifiedAsyncMode->valuestring != NULL) {
      if (0 == strcmp("sync", specifiedAsyncMode->valuestring)) {
        g_queryInfo.specifiedQueryInfo.asyncMode = SYNC_MODE;
      } else if (0 == strcmp("async", specifiedAsyncMode->valuestring)) {
        g_queryInfo.specifiedQueryInfo.asyncMode = ASYNC_MODE;
4220
      } else {
4221
        errorPrint("%s() LN%d, failed to read json, async mode input error\n",
4222
            __func__, __LINE__);
4223 4224 4225
        goto PARSE_OVER;
      }
    } else {
4226
      g_queryInfo.specifiedQueryInfo.asyncMode = SYNC_MODE;
4227
    }
4228

4229
    cJSON* interval = cJSON_GetObjectItem(specifiedQuery, "interval");
4230
    if (interval && interval->type == cJSON_Number) {
4231
      g_queryInfo.specifiedQueryInfo.subscribeInterval = interval->valueint;
4232
    } else if (!interval) {
4233 4234
      //printf("failed to read json, subscribe interval no found\n");
      //goto PARSE_OVER;
4235
      g_queryInfo.specifiedQueryInfo.subscribeInterval = 10000;
4236
    }
4237

4238
    cJSON* restart = cJSON_GetObjectItem(specifiedQuery, "restart");
4239
    if (restart && restart->type == cJSON_String && restart->valuestring != NULL) {
4240
      if (0 == strcmp("yes", restart->valuestring)) {
4241
        g_queryInfo.specifiedQueryInfo.subscribeRestart = true;
4242
      } else if (0 == strcmp("no", restart->valuestring)) {
4243
        g_queryInfo.specifiedQueryInfo.subscribeRestart = false;
4244
      } else {
4245
        printf("ERROR: failed to read json, subscribe restart error\n");
4246 4247 4248
        goto PARSE_OVER;
      }
    } else {
4249
      g_queryInfo.specifiedQueryInfo.subscribeRestart = true;
4250
    }
4251

4252
    cJSON* keepProgress = cJSON_GetObjectItem(specifiedQuery, "keepProgress");
4253 4254 4255
    if (keepProgress
            && keepProgress->type == cJSON_String
            && keepProgress->valuestring != NULL) {
4256
      if (0 == strcmp("yes", keepProgress->valuestring)) {
4257
        g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 1;
4258
      } else if (0 == strcmp("no", keepProgress->valuestring)) {
4259
        g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 0;
4260
      } else {
4261
        printf("ERROR: failed to read json, subscribe keepProgress error\n");
4262 4263 4264
        goto PARSE_OVER;
      }
    } else {
4265
      g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 0;
4266 4267
    }

4268
    // sqls
4269
    cJSON* superSqls = cJSON_GetObjectItem(specifiedQuery, "sqls");
4270
    if (!superSqls) {
4271
      g_queryInfo.specifiedQueryInfo.sqlCount = 0;
4272
    } else if (superSqls->type != cJSON_Array) {
4273 4274
      errorPrint("%s() LN%d, failed to read json, super sqls not found\n",
          __func__, __LINE__);
4275
      goto PARSE_OVER;
4276
    } else {
4277 4278
      int superSqlSize = cJSON_GetArraySize(superSqls);
      if (superSqlSize > MAX_QUERY_SQL_COUNT) {
4279 4280
        errorPrint("%s() LN%d, failed to read json, query sql size overflow, max is %d\n",
           __func__, __LINE__, MAX_QUERY_SQL_COUNT);
4281 4282
        goto PARSE_OVER;
      }
4283

4284
      g_queryInfo.specifiedQueryInfo.sqlCount = superSqlSize;
4285 4286 4287
      for (int j = 0; j < superSqlSize; ++j) {
        cJSON* sql = cJSON_GetArrayItem(superSqls, j);
        if (sql == NULL) continue;
4288

4289 4290
        cJSON *sqlStr = cJSON_GetObjectItem(sql, "sql");
        if (!sqlStr || sqlStr->type != cJSON_String || sqlStr->valuestring == NULL) {
4291
          printf("ERROR: failed to read json, sql not found\n");
4292 4293
          goto PARSE_OVER;
        }
4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307
        tstrncpy(g_queryInfo.specifiedQueryInfo.sql[j],
                sqlStr->valuestring, MAX_QUERY_SQL_LENGTH);

        cJSON* resubAfterConsume =
            cJSON_GetObjectItem(specifiedQuery, "resubAfterConsume");
        if (resubAfterConsume
                && resubAfterConsume->type == cJSON_Number) {
            g_queryInfo.specifiedQueryInfo.resubAfterConsume[j]
                = resubAfterConsume->valueint;
        } else if (!resubAfterConsume) {
            //printf("failed to read json, subscribe interval no found\n");
            //goto PARSE_OVER;
            g_queryInfo.specifiedQueryInfo.resubAfterConsume[j] = 1;
        }
H
hzcheng 已提交
4308

4309
        cJSON *result = cJSON_GetObjectItem(sql, "result");
4310 4311 4312 4313
        if ((NULL != result) && (result->type == cJSON_String)
                && (result->valuestring != NULL)) {
          tstrncpy(g_queryInfo.specifiedQueryInfo.result[j],
                  result->valuestring, MAX_FILE_NAME_LEN);
4314
        } else if (NULL == result) {
4315 4316
          memset(g_queryInfo.specifiedQueryInfo.result[j],
                  0, MAX_FILE_NAME_LEN);
4317
        } else {
4318
          printf("ERROR: failed to read json, super query result file not found\n");
4319
          goto PARSE_OVER;
4320
        }
4321 4322 4323
      }
    }
  }
4324

4325
  // super_table_query
4326 4327
  cJSON *superQuery = cJSON_GetObjectItem(root, "super_table_query");
  if (!superQuery) {
4328
    g_queryInfo.superQueryInfo.threadCnt = 1;
4329 4330
    g_queryInfo.superQueryInfo.sqlCount = 0;
  } else if (superQuery->type != cJSON_Object) {
4331
    printf("ERROR: failed to read json, sub_table_query not found\n");
4332 4333
    ret = true;
    goto PARSE_OVER;
H
hzcheng 已提交
4334
  } else {
4335
    cJSON* subrate = cJSON_GetObjectItem(superQuery, "query_interval");
4336
    if (subrate && subrate->type == cJSON_Number) {
4337
      g_queryInfo.superQueryInfo.queryInterval = subrate->valueint;
4338
    } else if (!subrate) {
4339
      g_queryInfo.superQueryInfo.queryInterval = 0;
4340 4341 4342 4343
    }

    cJSON* superQueryTimes = cJSON_GetObjectItem(superQuery, "query_times");
    if (superQueryTimes && superQueryTimes->type == cJSON_Number) {
4344 4345 4346
      if (superQueryTimes->valueint <= 0) {
        errorPrint("%s() LN%d, failed to read json, query_times: %"PRId64", need be a valid (>0) number\n",
          __func__, __LINE__, superQueryTimes->valueint);
4347 4348
        goto PARSE_OVER;
      }
4349 4350 4351 4352
      g_queryInfo.superQueryInfo.queryTimes = superQueryTimes->valueint;
    } else if (!superQueryTimes) {
      g_queryInfo.superQueryInfo.queryTimes = g_args.query_times;
    } else {
4353 4354
      errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
          __func__, __LINE__);
4355
      goto PARSE_OVER;
4356
    }
4357

4358
    cJSON* threads = cJSON_GetObjectItem(superQuery, "threads");
4359
    if (threads && threads->type == cJSON_Number) {
4360 4361 4362 4363 4364 4365
      if (threads->valueint <= 0) {
        errorPrint("%s() LN%d, failed to read json, threads input mistake\n",
          __func__, __LINE__);
        goto PARSE_OVER;

      }
4366
      g_queryInfo.superQueryInfo.threadCnt = threads->valueint;
4367
    } else if (!threads) {
4368
      g_queryInfo.superQueryInfo.threadCnt = 1;
4369
    }
4370

4371
    //cJSON* subTblCnt = cJSON_GetObjectItem(superQuery, "childtable_count");
4372
    //if (subTblCnt && subTblCnt->type == cJSON_Number) {
4373
    //  g_queryInfo.superQueryInfo.childTblCount = subTblCnt->valueint;
4374
    //} else if (!subTblCnt) {
4375
    //  g_queryInfo.superQueryInfo.childTblCount = 0;
4376
    //}
4377

4378
    cJSON* stblname = cJSON_GetObjectItem(superQuery, "stblname");
4379 4380 4381 4382
    if (stblname && stblname->type == cJSON_String
        && stblname->valuestring != NULL) {
      tstrncpy(g_queryInfo.superQueryInfo.sTblName, stblname->valuestring,
          MAX_TB_NAME_SIZE);
4383
    } else {
4384 4385
      errorPrint("%s() LN%d, failed to read json, super table name input error\n",
          __func__, __LINE__);
4386 4387
      goto PARSE_OVER;
    }
4388

4389 4390 4391 4392 4393 4394 4395
    cJSON* superAsyncMode = cJSON_GetObjectItem(superQuery, "mode");
    if (superAsyncMode && superAsyncMode->type == cJSON_String
        && superAsyncMode->valuestring != NULL) {
      if (0 == strcmp("sync", superAsyncMode->valuestring)) {
        g_queryInfo.superQueryInfo.asyncMode = SYNC_MODE;
      } else if (0 == strcmp("async", superAsyncMode->valuestring)) {
        g_queryInfo.superQueryInfo.asyncMode = ASYNC_MODE;
4396
      } else {
4397
        errorPrint("%s() LN%d, failed to read json, async mode input error\n",
4398
            __func__, __LINE__);
4399 4400 4401
        goto PARSE_OVER;
      }
    } else {
4402
      g_queryInfo.superQueryInfo.asyncMode = SYNC_MODE;
4403
    }
4404

4405 4406 4407 4408 4409 4410 4411 4412 4413
    cJSON* superInterval = cJSON_GetObjectItem(superQuery, "interval");
    if (superInterval && superInterval->type == cJSON_Number) {
      if (superInterval->valueint < 0) {
        errorPrint("%s() LN%d, failed to read json, interval input mistake\n",
            __func__, __LINE__);
        goto PARSE_OVER;
      }
      g_queryInfo.superQueryInfo.subscribeInterval = superInterval->valueint;
    } else if (!superInterval) {
4414 4415
      //printf("failed to read json, subscribe interval no found\n");
      //goto PARSE_OVER;
4416
      g_queryInfo.superQueryInfo.subscribeInterval = 10000;
4417
    }
4418

4419
    cJSON* subrestart = cJSON_GetObjectItem(superQuery, "restart");
4420 4421
    if (subrestart && subrestart->type == cJSON_String
        && subrestart->valuestring != NULL) {
4422
      if (0 == strcmp("yes", subrestart->valuestring)) {
4423
        g_queryInfo.superQueryInfo.subscribeRestart = true;
4424
      } else if (0 == strcmp("no", subrestart->valuestring)) {
4425
        g_queryInfo.superQueryInfo.subscribeRestart = false;
4426
      } else {
4427
        printf("ERROR: failed to read json, subscribe restart error\n");
4428 4429 4430
        goto PARSE_OVER;
      }
    } else {
4431
      g_queryInfo.superQueryInfo.subscribeRestart = true;
4432
    }
4433

4434 4435 4436 4437 4438
    cJSON* superkeepProgress = cJSON_GetObjectItem(superQuery, "keepProgress");
    if (superkeepProgress &&
            superkeepProgress->type == cJSON_String
            && superkeepProgress->valuestring != NULL) {
      if (0 == strcmp("yes", superkeepProgress->valuestring)) {
4439
        g_queryInfo.superQueryInfo.subscribeKeepProgress = 1;
4440
      } else if (0 == strcmp("no", superkeepProgress->valuestring)) {
4441
        g_queryInfo.superQueryInfo.subscribeKeepProgress = 0;
4442
      } else {
4443
        printf("ERROR: failed to read json, subscribe super table keepProgress error\n");
4444 4445 4446
        goto PARSE_OVER;
      }
    } else {
4447
      g_queryInfo.superQueryInfo.subscribeKeepProgress = 0;
4448
    }
4449

4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461
    cJSON* superResubAfterConsume =
            cJSON_GetObjectItem(superQuery, "resubAfterConsume");
    if (superResubAfterConsume
            && superResubAfterConsume->type == cJSON_Number) {
        g_queryInfo.superQueryInfo.resubAfterConsume =
            superResubAfterConsume->valueint;
    } else if (!superResubAfterConsume) {
        //printf("failed to read json, subscribe interval no found\n");
        ////goto PARSE_OVER;
        g_queryInfo.superQueryInfo.resubAfterConsume = 1;
    }

4462
    // sqls
4463
    cJSON* subsqls = cJSON_GetObjectItem(superQuery, "sqls");
4464
    if (!subsqls) {
4465
      g_queryInfo.superQueryInfo.sqlCount = 0;
4466
    } else if (subsqls->type != cJSON_Array) {
4467 4468
      errorPrint("%s() LN%d: failed to read json, super sqls not found\n",
          __func__, __LINE__);
4469
      goto PARSE_OVER;
4470
    } else {
4471 4472
      int superSqlSize = cJSON_GetArraySize(subsqls);
      if (superSqlSize > MAX_QUERY_SQL_COUNT) {
4473 4474
        errorPrint("%s() LN%d, failed to read json, query sql size overflow, max is %d\n",
           __func__, __LINE__, MAX_QUERY_SQL_COUNT);
4475 4476
        goto PARSE_OVER;
      }
4477

4478
      g_queryInfo.superQueryInfo.sqlCount = superSqlSize;
4479
      for (int j = 0; j < superSqlSize; ++j) {
4480 4481
        cJSON* sql = cJSON_GetArrayItem(subsqls, j);
        if (sql == NULL) continue;
4482

4483
        cJSON *sqlStr = cJSON_GetObjectItem(sql, "sql");
4484 4485 4486 4487
        if (!sqlStr || sqlStr->type != cJSON_String
            || sqlStr->valuestring == NULL) {
          errorPrint("%s() LN%d, failed to read json, sql not found\n",
              __func__, __LINE__);
4488 4489
          goto PARSE_OVER;
        }
4490 4491
        tstrncpy(g_queryInfo.superQueryInfo.sql[j], sqlStr->valuestring,
            MAX_QUERY_SQL_LENGTH);
4492 4493

        cJSON *result = cJSON_GetObjectItem(sql, "result");
4494 4495 4496 4497
        if (result != NULL && result->type == cJSON_String
            && result->valuestring != NULL){
          tstrncpy(g_queryInfo.superQueryInfo.result[j],
              result->valuestring, MAX_FILE_NAME_LEN);
4498
        } else if (NULL == result) {
4499
          memset(g_queryInfo.superQueryInfo.result[j], 0, MAX_FILE_NAME_LEN);
4500
        }  else {
4501 4502
          errorPrint("%s() LN%d, failed to read json, sub query result file not found\n",
              __func__, __LINE__);
4503
          goto PARSE_OVER;
4504
        }
4505 4506
      }
    }
H
hzcheng 已提交
4507 4508
  }

4509
  ret = true;
H
hzcheng 已提交
4510

4511 4512 4513
PARSE_OVER:
  return ret;
}
H
hzcheng 已提交
4514

4515
static bool getInfoFromJsonFile(char* file) {
4516
    debugPrint("%s %d %s\n", __func__, __LINE__, file);
4517

4518 4519 4520 4521 4522
  FILE *fp = fopen(file, "r");
  if (!fp) {
    printf("failed to read %s, reason:%s\n", file, strerror(errno));
    return false;
  }
H
Hui Li 已提交
4523

4524
  bool  ret = false;
4525
  int   maxLen = 6400000;
4526 4527 4528 4529 4530 4531 4532
  char *content = calloc(1, maxLen + 1);
  int   len = fread(content, 1, maxLen, fp);
  if (len <= 0) {
    free(content);
    fclose(fp);
    printf("failed to read %s, content is null", file);
    return false;
H
hzcheng 已提交
4533
  }
H
Hui Li 已提交
4534

4535 4536 4537
  content[len] = 0;
  cJSON* root = cJSON_Parse(content);
  if (root == NULL) {
4538
    printf("ERROR: failed to cjson parse %s, invalid json format\n", file);
4539 4540
    goto PARSE_OVER;
  }
H
Hui Li 已提交
4541

4542 4543 4544
  cJSON* filetype = cJSON_GetObjectItem(root, "filetype");
  if (filetype && filetype->type == cJSON_String && filetype->valuestring != NULL) {
    if (0 == strcasecmp("insert", filetype->valuestring)) {
4545
      g_args.test_mode = INSERT_TEST;
4546
    } else if (0 == strcasecmp("query", filetype->valuestring)) {
4547
      g_args.test_mode = QUERY_TEST;
4548
    } else if (0 == strcasecmp("subscribe", filetype->valuestring)) {
4549
      g_args.test_mode = SUBSCRIBE_TEST;
4550
    } else {
4551
      printf("ERROR: failed to read json, filetype not support\n");
4552 4553 4554
      goto PARSE_OVER;
    }
  } else if (!filetype) {
4555
    g_args.test_mode = INSERT_TEST;
4556
  } else {
4557
    printf("ERROR: failed to read json, filetype not found\n");
4558 4559
    goto PARSE_OVER;
  }
H
hzcheng 已提交
4560

4561
  if (INSERT_TEST == g_args.test_mode) {
4562
    ret = getMetaFromInsertJsonFile(root);
4563 4564
  } else if ((QUERY_TEST == g_args.test_mode)
          || (SUBSCRIBE_TEST == g_args.test_mode)) {
4565 4566
    ret = getMetaFromQueryJsonFile(root);
  } else {
4567 4568
    errorPrint("%s() LN%d, input json file type error! please input correct file type: insert or query or subscribe\n",
            __func__, __LINE__);
4569
    goto PARSE_OVER;
4570
  }
4571 4572 4573 4574

PARSE_OVER:
  free(content);
  cJSON_Delete(root);
H
hzcheng 已提交
4575
  fclose(fp);
4576 4577
  return ret;
}
H
hzcheng 已提交
4578

4579
static void prepareSampleData() {
4580
  for (int i = 0; i < g_Dbs.dbCount; i++) {
4581 4582 4583
    for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
      if (g_Dbs.db[i].superTbls[j].tagsFile[0] != 0) {
        (void)readTagFromCsvFileToMem(&g_Dbs.db[i].superTbls[j]);
S
Shuaiqiang Chang 已提交
4584
      }
4585 4586 4587 4588
    }
  }
}

4589
static void postFreeResource() {
4590
  tmfclose(g_fpOfInsertResult);
4591
  for (int i = 0; i < g_Dbs.dbCount; i++) {
4592
    for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
4593 4594 4595
      if (0 != g_Dbs.db[i].superTbls[j].colsOfCreateChildTable) {
        free(g_Dbs.db[i].superTbls[j].colsOfCreateChildTable);
        g_Dbs.db[i].superTbls[j].colsOfCreateChildTable = NULL;
S
Shuaiqiang Chang 已提交
4596
      }
4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608
      if (0 != g_Dbs.db[i].superTbls[j].sampleDataBuf) {
        free(g_Dbs.db[i].superTbls[j].sampleDataBuf);
        g_Dbs.db[i].superTbls[j].sampleDataBuf = NULL;
      }
      if (0 != g_Dbs.db[i].superTbls[j].tagDataBuf) {
        free(g_Dbs.db[i].superTbls[j].tagDataBuf);
        g_Dbs.db[i].superTbls[j].tagDataBuf = NULL;
      }
      if (0 != g_Dbs.db[i].superTbls[j].childTblName) {
        free(g_Dbs.db[i].superTbls[j].childTblName);
        g_Dbs.db[i].superTbls[j].childTblName = NULL;
      }
S
Shuaiqiang Chang 已提交
4609
    }
4610 4611
  }
}
S
Shuaiqiang Chang 已提交
4612

4613 4614 4615
static int getRowDataFromSample(
        char* dataBuf, int64_t maxLen, int64_t timestamp,
      SSuperTable* superTblInfo, int64_t* sampleUsePos) {
4616
  if ((*sampleUsePos) == MAX_SAMPLES_ONCE_FROM_FILE) {
4617
/*    int ret = readSampleFromCsvFileToMem(superTblInfo);
4618
    if (0 != ret) {
4619
      tmfree(superTblInfo->sampleDataBuf);
4620
      superTblInfo->sampleDataBuf = NULL;
4621 4622
      return -1;
    }
4623
*/
4624 4625
    *sampleUsePos = 0;
  }
S
Shuaiqiang Chang 已提交
4626

4627
  int    dataLen = 0;
4628

4629 4630 4631 4632
  dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen,
          "(%" PRId64 ", ", timestamp);
  dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen,
          "%s", superTblInfo->sampleDataBuf + superTblInfo->lenOfOneRow * (*sampleUsePos));
4633
  dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")");
S
Shuaiqiang Chang 已提交
4634

4635
  (*sampleUsePos)++;
4636

4637 4638
  return dataLen;
}
S
Shuaiqiang Chang 已提交
4639

4640 4641
static int64_t generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stbInfo) {
  int64_t   dataLen = 0;
4642
  char  *pstr = recBuf;
4643
  int64_t maxLen = MAX_DATA_SIZE;
4644

4645
  dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "(%" PRId64 ",", timestamp);
4646

4647
  for (int i = 0; i < stbInfo->columnCount; i++) {
4648 4649
    if ((0 == strncasecmp(stbInfo->columns[i].dataType, "BINARY", strlen("BINARY")))
            || (0 == strncasecmp(stbInfo->columns[i].dataType, "NCHAR", strlen("NCHAR")))) {
4650
      if (stbInfo->columns[i].dataLen > TSDB_MAX_BINARY_LEN) {
4651
        errorPrint( "binary or nchar length overflow, max size:%u\n",
4652
                (uint32_t)TSDB_MAX_BINARY_LEN);
4653
        return -1;
4654
      }
4655

4656 4657
      char* buf = (char*)calloc(stbInfo->columns[i].dataLen+1, 1);
      if (NULL == buf) {
4658
        errorPrint( "calloc failed! size:%d\n", stbInfo->columns[i].dataLen);
4659
        return -1;
4660 4661
      }
      rand_string(buf, stbInfo->columns[i].dataLen);
4662
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "\'%s\',", buf);
4663
      tmfree(buf);
4664
    } else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4665
                "INT", 3)) {
4666
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4667
              "%d,", rand_int());
4668
    } else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4669
                "BIGINT", 6)) {
4670
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4671
              "%"PRId64",", rand_bigint());
4672
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4673
                "FLOAT", 5)) {
4674
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4675
              "%f,", rand_float());
4676
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4677
                "DOUBLE", 6)) {
4678
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4679
              "%f,", rand_double());
4680
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4681
                "SMALLINT", 8)) {
4682
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4683
          "%d,", rand_smallint());
4684
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4685
          "TINYINT", strlen("TINYINT"))) {
4686
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4687
          "%d,", rand_tinyint());
4688
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4689
          "BOOL", strlen("BOOL"))) {
4690
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4691
          "%d,", rand_bool());
4692
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4693
          "TIMESTAMP", strlen("TIMESTAMP"))) {
4694
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4695
          "%"PRId64",", rand_bigint());
4696
    }  else {
4697
      errorPrint( "No support data type: %s\n", stbInfo->columns[i].dataType);
4698
      return -1;
4699
    }
S
Shuaiqiang Chang 已提交
4700
  }
4701

4702
  dataLen -= 1;
4703
  dataLen += snprintf(pstr + dataLen, maxLen - dataLen, ")");
4704

4705 4706 4707
  verbosePrint("%s() LN%d, recBuf:\n\t%s\n", __func__, __LINE__, recBuf);

  return strlen(recBuf);
4708
}
S
Shuaiqiang Chang 已提交
4709

4710
static int64_t generateData(char *recBuf, char **data_type,
4711
        int num_of_cols, int64_t timestamp, int lenOfBinary) {
4712 4713
  memset(recBuf, 0, MAX_DATA_SIZE);
  char *pstr = recBuf;
4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727
  pstr += sprintf(pstr, "(%" PRId64, timestamp);
  int c = 0;

  for (; c < MAX_NUM_DATATYPE; c++) {
    if (data_type[c] == NULL) {
      break;
    }
  }

  if (0 == c) {
    perror("data type error!");
    exit(-1);
  }

4728
  for (int i = 0; i < c; i++) {
4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739
    if (strcasecmp(data_type[i % c], "TINYINT") == 0) {
      pstr += sprintf(pstr, ",%d", rand_tinyint() );
    } else if (strcasecmp(data_type[i % c], "SMALLINT") == 0) {
      pstr += sprintf(pstr, ",%d", rand_smallint());
    } else if (strcasecmp(data_type[i % c], "INT") == 0) {
      pstr += sprintf(pstr, ",%d", rand_int());
    } else if (strcasecmp(data_type[i % c], "BIGINT") == 0) {
      pstr += sprintf(pstr, ",%" PRId64, rand_bigint());
    } else if (strcasecmp(data_type[i % c], "FLOAT") == 0) {
      pstr += sprintf(pstr, ",%10.4f", rand_float());
    } else if (strcasecmp(data_type[i % c], "DOUBLE") == 0) {
4740
      double t = rand_double();
4741 4742
      pstr += sprintf(pstr, ",%20.8f", t);
    } else if (strcasecmp(data_type[i % c], "BOOL") == 0) {
4743
      bool b = rand_bool() & 1;
4744 4745
      pstr += sprintf(pstr, ",%s", b ? "true" : "false");
    } else if (strcasecmp(data_type[i % c], "BINARY") == 0) {
4746 4747
      char *s = malloc(lenOfBinary);
      rand_string(s, lenOfBinary);
4748
      pstr += sprintf(pstr, ",\"%s\"", s);
4749
      free(s);
4750
    } else if (strcasecmp(data_type[i % c], "NCHAR") == 0) {
4751 4752
      char *s = malloc(lenOfBinary);
      rand_string(s, lenOfBinary);
4753
      pstr += sprintf(pstr, ",\"%s\"", s);
4754 4755 4756
      free(s);
    }

4757
    if (strlen(recBuf) > MAX_DATA_SIZE) {
4758 4759 4760 4761 4762 4763 4764
      perror("column length too long, abort");
      exit(-1);
    }
  }

  pstr += sprintf(pstr, ")");

4765 4766
  verbosePrint("%s() LN%d, recBuf:\n\t%s\n", __func__, __LINE__, recBuf);

4767
  return (int32_t)strlen(recBuf);
4768 4769
}

4770
static int prepareSampleDataForSTable(SSuperTable *superTblInfo) {
4771 4772
  char* sampleDataBuf = NULL;

4773
  sampleDataBuf = calloc(
4774
            superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, 1);
4775
  if (sampleDataBuf == NULL) {
4776
      errorPrint("%s() LN%d, Failed to calloc %"PRIu64" Bytes, reason:%s\n",
4777
              __func__, __LINE__,
4778
              superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE,
4779
              strerror(errno));
4780
      return -1;
4781
  }
4782

4783 4784 4785 4786
  superTblInfo->sampleDataBuf = sampleDataBuf;
  int ret = readSampleFromCsvFileToMem(superTblInfo);

  if (0 != ret) {
4787 4788
      errorPrint("%s() LN%d, read sample from csv file failed.\n",
          __func__, __LINE__);
4789
      tmfree(sampleDataBuf);
4790
      superTblInfo->sampleDataBuf = NULL;
4791
      return -1;
H
Hui Li 已提交
4792
  }
4793

4794 4795 4796
  return 0;
}

4797
static int64_t execInsert(threadInfo *pThreadInfo, char *buffer, uint64_t k)
4798 4799
{
  int affectedRows;
4800
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
4801

4802 4803
  verbosePrint("[%d] %s() LN%d %s\n", pThreadInfo->threadID,
            __func__, __LINE__, buffer);
4804
  if (superTblInfo) {
4805
    if (0 == strncasecmp(superTblInfo->insertMode, "taosc", strlen("taosc"))) {
4806
      affectedRows = queryDbExec(pThreadInfo->taos, buffer, INSERT_TYPE, false);
4807
    } else if (0 == strncasecmp(superTblInfo->insertMode, "rest", strlen("rest"))) {
4808 4809
      if (0 != postProceSql(g_Dbs.host, &g_Dbs.serv_addr, g_Dbs.port,
                  buffer, NULL /* not set result file */)) {
4810
        affectedRows = -1;
4811 4812
        printf("========restful return fail, threadID[%d]\n",
            pThreadInfo->threadID);
4813 4814 4815
      } else {
        affectedRows = k;
      }
4816 4817 4818 4819
    } else {
      errorPrint("%s() LN%d: unknown insert mode: %s\n",
        __func__, __LINE__, superTblInfo->insertMode);
      affectedRows = 0;
4820
    }
4821
  } else {
4822
    affectedRows = queryDbExec(pThreadInfo->taos, buffer, INSERT_TYPE, false);
4823 4824 4825 4826 4827
  }

  return affectedRows;
}

4828 4829
static void getTableName(char *pTblName,
        threadInfo* pThreadInfo, uint64_t tableSeq)
4830 4831
{
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
4832 4833
  if ((superTblInfo)
          && (AUTO_CREATE_SUBTBL != superTblInfo->autoCreateTable)) {
4834
    if (superTblInfo->childTblLimit > 0) {
4835
        snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s",
4836 4837
            superTblInfo->childTblName +
            (tableSeq - superTblInfo->childTblOffset) * TSDB_TABLE_NAME_LEN);
4838
    } else {
4839

4840
        verbosePrint("[%d] %s() LN%d: from=%"PRIu64" count=%"PRId64" seq=%"PRIu64"\n",
4841 4842
                pThreadInfo->threadID, __func__, __LINE__,
                pThreadInfo->start_table_from,
4843 4844 4845 4846 4847
                pThreadInfo->ntables, tableSeq);
        snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s",
            superTblInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN);
    }
  } else {
4848
    snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%"PRIu64"",
4849
        g_args.tb_prefix, tableSeq);
4850 4851 4852
  }
}

4853
static int64_t generateDataTail(
4854
        SSuperTable* superTblInfo,
4855
        uint64_t batch, char* buffer, int64_t remainderBufLen, int64_t insertRows,
4856
        uint64_t startFrom, int64_t startTime, int64_t *pSamplePos, int64_t *dataLen) {
4857 4858
  uint64_t len = 0;
  uint32_t ncols_per_record = 1; // count first col ts
4859

4860 4861
  char *pstr = buffer;

4862
  if (superTblInfo == NULL) {
4863
    uint32_t datatypeSeq = 0;
4864 4865 4866 4867
    while(g_args.datatype[datatypeSeq]) {
        datatypeSeq ++;
        ncols_per_record ++;
    }
4868 4869
  }

4870
  verbosePrint("%s() LN%d batch=%"PRIu64"\n", __func__, __LINE__, batch);
4871

4872
  uint64_t k = 0;
4873
  for (k = 0; k < batch;) {
4874
    char data[MAX_DATA_SIZE];
4875 4876
    memset(data, 0, MAX_DATA_SIZE);

4877
    int64_t retLen = 0;
4878

4879 4880
    if (superTblInfo) {
      if (0 == strncasecmp(superTblInfo->dataSource,
4881 4882
                    "sample", strlen("sample"))) {
          retLen = getRowDataFromSample(
4883 4884
                    data,
                    remainderBufLen,
4885
                    startTime + superTblInfo->timeStampStep * k,
4886
                    superTblInfo,
4887
                    pSamplePos);
4888
      } else if (0 == strncasecmp(superTblInfo->dataSource,
4889
                   "rand", strlen("rand"))) {
4890

4891
        int64_t randTail = superTblInfo->timeStampStep * k;
4892 4893 4894 4895
        if (superTblInfo->disorderRatio > 0) {
          int rand_num = taosRandom() % 100;
          if(rand_num < superTblInfo->disorderRatio) {
            randTail = (randTail + (taosRandom() % superTblInfo->disorderRange + 1)) * (-1);
4896
            debugPrint("rand data generated, back %"PRId64"\n", randTail);
4897
          }
4898 4899
        }

4900
        int64_t d = startTime
4901 4902
                + randTail;
        retLen = generateRowData(
4903
                      data,
4904
                      d,
4905
                      superTblInfo);
4906
      }
4907

4908 4909 4910
      if (retLen > remainderBufLen) {
        break;
      }
4911

4912
      pstr += snprintf(pstr , retLen + 1, "%s", data);
4913 4914 4915
      k++;
      len += retLen;
      remainderBufLen -= retLen;
4916
    } else {
4917 4918
      char **data_type = g_args.datatype;
      int lenOfBinary = g_args.len_of_binary;
4919

4920 4921 4922 4923 4924 4925
      int64_t randTail = DEFAULT_TIMESTAMP_STEP * k;

      if (g_args.disorderRatio != 0) {
        int rand_num = taosRandom() % 100;
        if (rand_num < g_args.disorderRatio) {
          randTail = (randTail + (taosRandom() % g_args.disorderRange + 1)) * (-1);
4926

4927 4928
          debugPrint("rand data generated, back %"PRId64"\n", randTail);
        }
4929
      } else {
4930 4931 4932 4933
        randTail = DEFAULT_TIMESTAMP_STEP * k;
      }

      retLen = generateData(data, data_type,
4934
                  ncols_per_record,
4935
                  startTime + randTail,
4936
                  lenOfBinary);
4937

4938 4939 4940
      if (len > remainderBufLen)
        break;

4941
      pstr += sprintf(pstr, "%s", data);
4942 4943 4944
      k++;
      len += retLen;
      remainderBufLen -= retLen;
4945 4946
    }

4947
    verbosePrint("%s() LN%d len=%"PRIu64" k=%"PRIu64" \nbuffer=%s\n",
4948
            __func__, __LINE__, len, k, buffer);
4949 4950

    startFrom ++;
4951

4952
    if (startFrom >= insertRows) {
4953
      break;
4954
    }
4955
  }
4956

4957 4958 4959
  *dataLen = len;
  return k;
}
4960

4961
static int generateSQLHead(char *tableName, int32_t tableSeq,
4962 4963
        threadInfo* pThreadInfo, SSuperTable* superTblInfo,
        char *buffer, int remainderBufLen)
4964 4965
{
  int len;
4966 4967 4968 4969

#define HEAD_BUFF_LEN    1024*24  // 16*1024 + (192+32)*2 + insert into ..
  char headBuf[HEAD_BUFF_LEN];

4970 4971 4972 4973
  if (superTblInfo) {
    if (AUTO_CREATE_SUBTBL == superTblInfo->autoCreateTable) {
      char* tagsValBuf = NULL;
      if (0 == superTblInfo->tagSource) {
4974
            tagsValBuf = generateTagVaulesForStb(superTblInfo, tableSeq);
4975 4976 4977 4978 4979 4980
      } else {
            tagsValBuf = getTagValueFromTagSample(
                    superTblInfo,
                    tableSeq % superTblInfo->tagSampleCount);
      }
      if (NULL == tagsValBuf) {
4981 4982
        errorPrint("%s() LN%d, tag buf failed to allocate  memory\n",
            __func__, __LINE__);
4983 4984 4985
        return -1;
      }

4986 4987 4988
      len = snprintf(
          headBuf,
                  HEAD_BUFF_LEN,
4989
                  "%s.%s using %s.%s tags %s values",
4990 4991 4992 4993 4994 4995 4996
                  pThreadInfo->db_name,
                  tableName,
                  pThreadInfo->db_name,
                  superTblInfo->sTblName,
                  tagsValBuf);
      tmfree(tagsValBuf);
    } else if (TBL_ALREADY_EXISTS == superTblInfo->childTblExists) {
4997 4998 4999
      len = snprintf(
          headBuf,
                  HEAD_BUFF_LEN,
5000
                  "%s.%s values",
5001
                  pThreadInfo->db_name,
5002
                  tableName);
5003
    } else {
5004 5005 5006
      len = snprintf(
          headBuf,
                  HEAD_BUFF_LEN,
5007
                  "%s.%s values",
5008 5009 5010 5011
                  pThreadInfo->db_name,
                  tableName);
    }
  } else {
5012 5013 5014
      len = snprintf(
          headBuf,
                  HEAD_BUFF_LEN,
5015
                  "%s.%s values",
5016 5017 5018 5019
                  pThreadInfo->db_name,
                  tableName);
  }

5020 5021 5022 5023 5024
  if (len > remainderBufLen)
    return -1;

  tstrncpy(buffer, headBuf, len + 1);

5025 5026 5027
  return len;
}

5028
static int64_t generateInterlaceDataBuffer(
5029 5030
        char *tableName, uint64_t batchPerTbl, uint64_t i, uint64_t batchPerTblTimes,
        uint64_t tableSeq,
5031
        threadInfo *pThreadInfo, char *buffer,
5032
        int64_t insertRows,
5033
        int64_t startTime,
5034
        uint64_t *pRemainderBufLen)
5035
{
5036
  assert(buffer);
5037 5038 5039 5040 5041 5042 5043 5044 5045 5046
  char *pstr = buffer;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;

  int headLen = generateSQLHead(tableName, tableSeq, pThreadInfo,
            superTblInfo, pstr, *pRemainderBufLen);

  if (headLen <= 0) {
    return 0;
  }
  // generate data buffer
5047
  verbosePrint("[%d] %s() LN%d i=%"PRIu64" buffer:\n%s\n",
5048 5049 5050 5051 5052
            pThreadInfo->threadID, __func__, __LINE__, i, buffer);

  pstr += headLen;
  *pRemainderBufLen -= headLen;

5053
  int64_t dataLen = 0;
5054

5055
  verbosePrint("[%d] %s() LN%d i=%"PRIu64" batchPerTblTimes=%"PRIu64" batchPerTbl = %"PRIu64"\n",
5056 5057 5058 5059 5060 5061 5062 5063 5064 5065
            pThreadInfo->threadID, __func__, __LINE__,
            i, batchPerTblTimes, batchPerTbl);

  if (superTblInfo) {
    if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) {
      startTime = taosGetTimestamp(pThreadInfo->time_precision);
    }
  } else {
      startTime = 1500000000000;
  }
5066

5067
  int64_t k = generateDataTail(
5068
    superTblInfo,
5069 5070 5071 5072
    batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0,
    startTime,
    &(pThreadInfo->samplePos), &dataLen);

5073
  if (k == batchPerTbl) {
5074 5075 5076
    pstr += dataLen;
    *pRemainderBufLen -= dataLen;
  } else {
5077
    debugPrint("%s() LN%d, generated data tail: %"PRIu64", not equal batch per table: %"PRIu64"\n",
5078
            __func__, __LINE__, k, batchPerTbl);
5079 5080
    pstr -= headLen;
    pstr[0] = '\0';
5081
    k = 0;
5082 5083 5084 5085 5086
  }

  return k;
}

5087
static int64_t generateProgressiveDataBuffer(
5088
        char *tableName,
5089
        int64_t tableSeq,
5090 5091
        threadInfo *pThreadInfo, char *buffer,
        int64_t insertRows,
5092
        uint64_t startFrom, int64_t startTime, int64_t *pSamplePos,
5093
        int64_t *pRemainderBufLen)
5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107
{
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;

  int ncols_per_record = 1; // count first col ts

  if (superTblInfo == NULL) {
    int datatypeSeq = 0;
    while(g_args.datatype[datatypeSeq]) {
        datatypeSeq ++;
        ncols_per_record ++;
    }
  }

  assert(buffer != NULL);
5108
  char *pstr = buffer;
5109

5110
  int64_t k = 0;
5111

5112
  memset(buffer, 0, *pRemainderBufLen);
5113

5114
  int64_t headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, superTblInfo,
5115
          buffer, *pRemainderBufLen);
5116 5117 5118 5119

  if (headLen <= 0) {
    return 0;
  }
5120
  pstr += headLen;
5121
  *pRemainderBufLen -= headLen;
5122

5123
  int64_t dataLen;
5124
  k = generateDataTail(superTblInfo,
5125
          g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, startFrom,
5126
          startTime,
5127
          pSamplePos, &dataLen);
5128

5129 5130
  return k;
}
5131

5132 5133 5134 5135 5136 5137 5138 5139 5140
static void printStatPerThread(threadInfo *pThreadInfo)
{
  fprintf(stderr, "====thread[%d] completed total inserted rows: %"PRIu64 ", total affected rows: %"PRIu64". %.2f records/second====\n",
          pThreadInfo->threadID,
          pThreadInfo->totalInsertRows,
          pThreadInfo->totalAffectedRows,
          (double)(pThreadInfo->totalAffectedRows / (pThreadInfo->totalDelay/1000.0)));
}

5141
static void* syncWriteInterlace(threadInfo *pThreadInfo) {
5142 5143
  debugPrint("[%d] %s() LN%d: ### interlace write\n",
         pThreadInfo->threadID, __func__, __LINE__);
5144

5145
  int64_t insertRows;
5146
  uint64_t interlaceRows;
5147

5148
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5149

5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162
  if (superTblInfo) {
    insertRows = superTblInfo->insertRows;

    if ((superTblInfo->interlaceRows == 0)
        && (g_args.interlace_rows > 0)) {
      interlaceRows = g_args.interlace_rows;
    } else {
      interlaceRows = superTblInfo->interlaceRows;
    }
  } else {
    insertRows = g_args.num_of_DPT;
    interlaceRows = g_args.interlace_rows;
  }
5163

5164
  if (interlaceRows > insertRows)
5165
    interlaceRows = insertRows;
5166

5167 5168
  if (interlaceRows > g_args.num_of_RPR)
    interlaceRows = g_args.num_of_RPR;
5169

5170 5171 5172 5173 5174 5175 5176 5177 5178 5179
  int insertMode;

  if (interlaceRows > 0) {
    insertMode = INTERLACE_INSERT_MODE;
  } else {
    insertMode = PROGRESSIVE_INSERT_MODE;
  }

  // TODO: prompt tbl count multple interlace rows and batch
  //
5180

5181
  uint64_t maxSqlLen = superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len;
5182
  char* buffer = calloc(maxSqlLen, 1);
5183
  if (NULL == buffer) {
5184
    errorPrint( "%s() LN%d, Failed to alloc %"PRIu64" Bytes, reason:%s\n",
5185
              __func__, __LINE__, maxSqlLen, strerror(errno));
5186 5187 5188
    return NULL;
  }

5189
  char tableName[TSDB_TABLE_NAME_LEN];
5190 5191 5192 5193

  pThreadInfo->totalInsertRows = 0;
  pThreadInfo->totalAffectedRows = 0;

5194
  int64_t nTimeStampStep = superTblInfo?superTblInfo->timeStampStep:DEFAULT_TIMESTAMP_STEP;
5195

5196
  uint64_t insert_interval =
5197
      superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
5198 5199
  uint64_t st = 0;
  uint64_t et = UINT64_MAX;
5200

5201 5202 5203
  uint64_t lastPrintTime = taosGetTimestampMs();
  uint64_t startTs = taosGetTimestampMs();
  uint64_t endTs;
5204

5205
  uint64_t tableSeq = pThreadInfo->start_table_from;
5206

5207
  debugPrint("[%d] %s() LN%d: start_table_from=%"PRIu64" ntables=%"PRId64" insertRows=%"PRIu64"\n",
5208
          pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->start_table_from,
5209 5210 5211 5212
          pThreadInfo->ntables, insertRows);

  int64_t startTime = pThreadInfo->start_time;

5213 5214
  uint64_t batchPerTbl = interlaceRows;
  uint64_t batchPerTblTimes;
5215

5216
  if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) {
5217
    batchPerTblTimes =
5218
        g_args.num_of_RPR / interlaceRows;
5219 5220 5221 5222
  } else {
    batchPerTblTimes = 1;
  }

5223
  uint64_t generatedRecPerTbl = 0;
5224
  bool flagSleep = true;
5225
  uint64_t sleepTimeTotal = 0;
5226

5227 5228 5229
  char *strInsertInto = "insert into ";
  int nInsertBufLen = strlen(strInsertInto);

5230
  while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) {
5231
    if ((flagSleep) && (insert_interval)) {
5232
        st = taosGetTimestampMs();
5233
        flagSleep = false;
5234 5235
    }
    // generate data
5236
    memset(buffer, 0, maxSqlLen);
5237
    uint64_t remainderBufLen = maxSqlLen;
5238

5239
    char *pstr = buffer;
5240 5241 5242 5243 5244

    int len = snprintf(pstr, nInsertBufLen + 1, "%s", strInsertInto);
    pstr += len;
    remainderBufLen -= len;

5245
    uint64_t recOfBatch = 0;
5246

5247
    for (uint64_t i = 0; i < batchPerTblTimes; i ++) {
5248
      getTableName(tableName, pThreadInfo, tableSeq);
5249 5250 5251
      if (0 == strlen(tableName)) {
        errorPrint("[%d] %s() LN%d, getTableName return null\n",
            pThreadInfo->threadID, __func__, __LINE__);
5252
        free(buffer);
5253 5254
        return NULL;
      }
5255

5256
      uint64_t oldRemainderLen = remainderBufLen;
5257
      int64_t generated = generateInterlaceDataBuffer(
5258 5259 5260 5261
        tableName, batchPerTbl, i, batchPerTblTimes,
        tableSeq,
        pThreadInfo, pstr,
        insertRows,
5262
        startTime,
5263
        &remainderBufLen);
5264

5265 5266
      debugPrint("[%d] %s() LN%d, generated records is %"PRId64"\n",
                  pThreadInfo->threadID, __func__, __LINE__, generated);
5267
      if (generated < 0) {
5268
        errorPrint("[%d] %s() LN%d, generated records is %"PRId64"\n",
5269
                  pThreadInfo->threadID, __func__, __LINE__, generated);
5270
        goto free_of_interlace;
5271 5272
      } else if (generated == 0) {
        break;
5273 5274
      }

5275
      tableSeq ++;
5276
      recOfBatch += batchPerTbl;
5277
      pstr += (oldRemainderLen - remainderBufLen);
5278
//      startTime += batchPerTbl * superTblInfo->timeStampStep;
5279
      pThreadInfo->totalInsertRows += batchPerTbl;
5280
      verbosePrint("[%d] %s() LN%d batchPerTbl=%"PRId64" recOfBatch=%"PRId64"\n",
5281 5282
                pThreadInfo->threadID, __func__, __LINE__,
                batchPerTbl, recOfBatch);
5283

5284 5285 5286 5287
      if (insertMode == INTERLACE_INSERT_MODE) {
          if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) {
            // turn to first table
            tableSeq = pThreadInfo->start_table_from;
5288
            generatedRecPerTbl += batchPerTbl;
5289 5290

            startTime = pThreadInfo->start_time
5291
              + generatedRecPerTbl * nTimeStampStep;
5292

5293 5294 5295 5296
            flagSleep = true;
            if (generatedRecPerTbl >= insertRows)
              break;

5297 5298 5299 5300
            int remainRows = insertRows - generatedRecPerTbl;
            if ((remainRows > 0) && (batchPerTbl > remainRows))
              batchPerTbl = remainRows;

5301 5302
            if (pThreadInfo->ntables * batchPerTbl < g_args.num_of_RPR)
                break;
5303
          }
5304 5305
      }

5306
      verbosePrint("[%d] %s() LN%d generatedRecPerTbl=%"PRId64" insertRows=%"PRId64"\n",
5307 5308 5309 5310
                pThreadInfo->threadID, __func__, __LINE__,
                generatedRecPerTbl, insertRows);

      if ((g_args.num_of_RPR - recOfBatch) < batchPerTbl)
5311 5312 5313
        break;
    }

5314
    verbosePrint("[%d] %s() LN%d recOfBatch=%"PRIu64" totalInsertRows=%"PRIu64"\n",
5315 5316 5317 5318 5319
              pThreadInfo->threadID, __func__, __LINE__, recOfBatch,
              pThreadInfo->totalInsertRows);
    verbosePrint("[%d] %s() LN%d, buffer=%s\n",
           pThreadInfo->threadID, __func__, __LINE__, buffer);

5320
    startTs = taosGetTimestampMs();
5321

5322 5323 5324 5325 5326 5327 5328
    if (recOfBatch == 0) {
      errorPrint("[%d] %s() LN%d try inserting records of batch is %"PRIu64"\n",
              pThreadInfo->threadID, __func__, __LINE__,
              recOfBatch);
      errorPrint("%s\n", "\tPlease check if the batch or the buffer length is proper value!\n");
      goto free_of_interlace;
    }
5329
    int64_t affectedRows = execInsert(pThreadInfo, buffer, recOfBatch);
5330

5331
    endTs = taosGetTimestampMs();
5332 5333
    uint64_t delay = endTs - startTs;
    performancePrint("%s() LN%d, insert execution time is %"PRIu64"ms\n",
5334
            __func__, __LINE__, delay);
5335 5336 5337
    verbosePrint("[%d] %s() LN%d affectedRows=%"PRId64"\n",
            pThreadInfo->threadID,
            __func__, __LINE__, affectedRows);
5338 5339 5340 5341 5342 5343

    if (delay > pThreadInfo->maxDelay) pThreadInfo->maxDelay = delay;
    if (delay < pThreadInfo->minDelay) pThreadInfo->minDelay = delay;
    pThreadInfo->cntDelay++;
    pThreadInfo->totalDelay += delay;

5344 5345
    if (recOfBatch != affectedRows) {
        errorPrint("[%d] %s() LN%d execInsert insert %"PRIu64", affected rows: %"PRId64"\n%s\n",
5346
                pThreadInfo->threadID, __func__, __LINE__,
5347
                recOfBatch, affectedRows, buffer);
5348
        goto free_of_interlace;
5349
    }
5350

5351
    pThreadInfo->totalAffectedRows += affectedRows;
5352

5353 5354
    int64_t  currentPrintTime = taosGetTimestampMs();
    if (currentPrintTime - lastPrintTime > 30*1000) {
5355
      printf("thread[%d] has currently inserted rows: %"PRIu64 ", affected rows: %"PRIu64 "\n",
5356 5357 5358
                    pThreadInfo->threadID,
                    pThreadInfo->totalInsertRows,
                    pThreadInfo->totalAffectedRows);
5359 5360
      lastPrintTime = currentPrintTime;
    }
5361

5362
    if ((insert_interval) && flagSleep) {
5363
      et = taosGetTimestampMs();
5364

5365 5366
      if (insert_interval > (et - st) ) {
        int sleepTime = insert_interval - (et -st);
5367 5368
        performancePrint("%s() LN%d sleep: %d ms for insert interval\n",
                    __func__, __LINE__, sleepTime);
5369 5370 5371
        taosMsleep(sleepTime); // ms
        sleepTimeTotal += insert_interval;
      }
5372
    }
5373 5374
  }

5375
free_of_interlace:
5376
  tmfree(buffer);
5377
  printStatPerThread(pThreadInfo);
5378 5379 5380
  return NULL;
}

5381 5382 5383 5384 5385 5386 5387 5388
// sync insertion
/*
   1 thread: 100 tables * 2000  rows/s
   1 thread: 10  tables * 20000 rows/s
   6 thread: 300 tables * 2000  rows/s

   2 taosinsertdata , 1 thread:  10  tables * 20000 rows/s
*/
5389
static void* syncWriteProgressive(threadInfo *pThreadInfo) {
5390
  debugPrint("%s() LN%d: ### progressive write\n", __func__, __LINE__);
5391

5392
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5393
  uint64_t maxSqlLen = superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len;
5394

5395
  char* buffer = calloc(maxSqlLen, 1);
5396
  if (NULL == buffer) {
5397
    errorPrint( "Failed to alloc %"PRIu64" Bytes, reason:%s\n",
5398
              maxSqlLen,
5399 5400 5401
              strerror(errno));
    return NULL;
  }
5402

5403 5404 5405
  uint64_t lastPrintTime = taosGetTimestampMs();
  uint64_t startTs = taosGetTimestampMs();
  uint64_t endTs;
5406

5407
  int64_t timeStampStep =
5408
      superTblInfo?superTblInfo->timeStampStep:DEFAULT_TIMESTAMP_STEP;
5409
/*  int insert_interval =
5410
      superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
5411 5412
  uint64_t st = 0;
  uint64_t et = 0xffffffff;
5413
  */
5414

5415 5416
  pThreadInfo->totalInsertRows = 0;
  pThreadInfo->totalAffectedRows = 0;
5417

5418
  pThreadInfo->samplePos = 0;
5419

5420
  for (uint64_t tableSeq =
5421
          pThreadInfo->start_table_from; tableSeq <= pThreadInfo->end_table_to;
5422
        tableSeq ++) {
5423
    int64_t start_time = pThreadInfo->start_time;
5424

5425
    int64_t insertRows = (superTblInfo)?superTblInfo->insertRows:g_args.num_of_DPT;
5426

5427 5428
    verbosePrint("%s() LN%d insertRows=%"PRId64"\n", __func__, __LINE__, insertRows);

5429
    for (uint64_t i = 0; i < insertRows;) {
5430
        /*
5431
      if (insert_interval) {
5432
            st = taosGetTimestampMs();
5433
      }
5434
      */
5435

5436 5437
      char tableName[TSDB_TABLE_NAME_LEN];
      getTableName(tableName, pThreadInfo, tableSeq);
5438
      verbosePrint("%s() LN%d: tid=%d seq=%"PRId64" tableName=%s\n",
5439 5440 5441
             __func__, __LINE__,
             pThreadInfo->threadID, tableSeq, tableName);

5442
      int64_t remainderBufLen = maxSqlLen;
5443 5444 5445 5446 5447 5448 5449 5450
      char *pstr = buffer;
      int nInsertBufLen = strlen("insert into ");

      int len = snprintf(pstr, nInsertBufLen + 1, "%s", "insert into ");

      pstr += len;
      remainderBufLen -= len;

5451
      int64_t generated = generateProgressiveDataBuffer(
5452
              tableName, tableSeq, pThreadInfo, pstr, insertRows,
5453
            i, start_time,
5454 5455
            &(pThreadInfo->samplePos),
            &remainderBufLen);
5456 5457 5458
      if (generated > 0)
        i += generated;
      else
5459
        goto free_of_progressive;
5460

5461
      start_time +=  generated * timeStampStep;
5462
      pThreadInfo->totalInsertRows += generated;
5463

5464
      startTs = taosGetTimestampMs();
5465

5466
      int64_t affectedRows = execInsert(pThreadInfo, buffer, generated);
5467

5468
      endTs = taosGetTimestampMs();
5469
      uint64_t delay = endTs - startTs;
5470 5471
      performancePrint("%s() LN%d, insert execution time is %"PRId64"ms\n",
              __func__, __LINE__, delay);
5472 5473 5474
      verbosePrint("[%d] %s() LN%d affectedRows=%"PRId64"\n",
            pThreadInfo->threadID,
            __func__, __LINE__, affectedRows);
5475

5476 5477 5478 5479
      if (delay > pThreadInfo->maxDelay) pThreadInfo->maxDelay = delay;
      if (delay < pThreadInfo->minDelay) pThreadInfo->minDelay = delay;
      pThreadInfo->cntDelay++;
      pThreadInfo->totalDelay += delay;
5480

5481 5482 5483 5484 5485
      if (affectedRows < 0) {
        errorPrint("%s() LN%d, affected rows: %"PRId64"\n",
                __func__, __LINE__, affectedRows);
        goto free_of_progressive;
      }
5486 5487 5488

      pThreadInfo->totalAffectedRows += affectedRows;

5489 5490
      int64_t  currentPrintTime = taosGetTimestampMs();
      if (currentPrintTime - lastPrintTime > 30*1000) {
5491
        printf("thread[%d] has currently inserted rows: %"PRId64 ", affected rows: %"PRId64 "\n",
5492 5493 5494
                    pThreadInfo->threadID,
                    pThreadInfo->totalInsertRows,
                    pThreadInfo->totalAffectedRows);
5495 5496 5497
        lastPrintTime = currentPrintTime;
      }

5498
      if (i >= insertRows)
5499
        break;
5500
/*
5501
      if (insert_interval) {
5502
        et = taosGetTimestampMs();
5503

5504 5505
        if (insert_interval > ((et - st)) ) {
            int sleep_time = insert_interval - (et -st);
5506 5507
            performancePrint("%s() LN%d sleep: %d ms for insert interval\n",
                    __func__, __LINE__, sleep_time);
5508 5509
            taosMsleep(sleep_time); // ms
        }
5510
      }
5511
      */
5512 5513
    }   // num_of_DPT

5514 5515
    if (g_args.verbose_print) {
      if ((tableSeq == pThreadInfo->ntables - 1) && superTblInfo &&
5516 5517
        (0 == strncasecmp(
                    superTblInfo->dataSource, "sample", strlen("sample")))) {
5518
          verbosePrint("%s() LN%d samplePos=%"PRId64"\n",
5519
                  __func__, __LINE__, pThreadInfo->samplePos);
5520
      }
5521
    }
5522
  } // tableSeq
5523

5524
free_of_progressive:
5525
  tmfree(buffer);
5526
  printStatPerThread(pThreadInfo);
5527
  return NULL;
H
Hui Li 已提交
5528 5529
}

5530 5531
static void* syncWrite(void *sarg) {

5532 5533
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5534

5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546
  int interlaceRows;

  if (superTblInfo) {
    if ((superTblInfo->interlaceRows == 0)
        && (g_args.interlace_rows > 0)) {
      interlaceRows = g_args.interlace_rows;
    } else {
      interlaceRows = superTblInfo->interlaceRows;
    }
  } else {
    interlaceRows = g_args.interlace_rows;
  }
5547

5548
  if (interlaceRows > 0) {
5549
    // interlace mode
5550
    return syncWriteInterlace(pThreadInfo);
5551 5552
  } else {
    // progressive mode
5553
    return syncWriteProgressive(pThreadInfo);
5554
  }
5555

5556 5557
}

5558
static void callBack(void *param, TAOS_RES *res, int code) {
5559 5560
  threadInfo* pThreadInfo = (threadInfo*)param;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5561

5562 5563
  int insert_interval =
      superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
5564
  if (insert_interval) {
5565 5566 5567
    pThreadInfo->et = taosGetTimestampMs();
    if ((pThreadInfo->et - pThreadInfo->st) < insert_interval) {
      taosMsleep(insert_interval - (pThreadInfo->et - pThreadInfo->st)); // ms
5568
    }
H
Hui Li 已提交
5569
  }
5570

5571
  char *buffer = calloc(1, pThreadInfo->superTblInfo->maxSqlLen);
5572
  char data[MAX_DATA_SIZE];
5573
  char *pstr = buffer;
5574 5575
  pstr += sprintf(pstr, "insert into %s.%s%"PRId64" values",
          pThreadInfo->db_name, pThreadInfo->tb_prefix,
5576 5577 5578 5579 5580 5581 5582 5583
          pThreadInfo->start_table_from);
//  if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) {
  if (pThreadInfo->counter >= g_args.num_of_RPR) {
    pThreadInfo->start_table_from++;
    pThreadInfo->counter = 0;
  }
  if (pThreadInfo->start_table_from > pThreadInfo->end_table_to) {
    tsem_post(&pThreadInfo->lock_sem);
5584 5585 5586 5587
    free(buffer);
    taos_free_result(res);
    return;
  }
5588

5589
  for (int i = 0; i < g_args.num_of_RPR; i++) {
5590
    int rand_num = taosRandom() % 100;
5591 5592
    if (0 != pThreadInfo->superTblInfo->disorderRatio
            && rand_num < pThreadInfo->superTblInfo->disorderRatio) {
5593 5594
      int64_t d = pThreadInfo->lastTs
          - (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1);
5595
      generateRowData(data, d, pThreadInfo->superTblInfo);
5596
    } else {
5597
      generateRowData(data, pThreadInfo->lastTs += 1000, pThreadInfo->superTblInfo);
H
Hui Li 已提交
5598
    }
5599
    pstr += sprintf(pstr, "%s", data);
5600
    pThreadInfo->counter++;
H
Hui Li 已提交
5601

5602
    if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) {
5603
      break;
H
Hui Li 已提交
5604 5605
    }
  }
5606

5607
  if (insert_interval) {
5608
    pThreadInfo->st = taosGetTimestampMs();
5609
  }
5610
  taos_query_a(pThreadInfo->taos, buffer, callBack, pThreadInfo);
5611
  free(buffer);
H
Hui Li 已提交
5612

5613
  taos_free_result(res);
H
Hui Li 已提交
5614 5615
}

5616
static void *asyncWrite(void *sarg) {
5617 5618
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5619

5620 5621 5622
  pThreadInfo->st = 0;
  pThreadInfo->et = 0;
  pThreadInfo->lastTs = pThreadInfo->start_time;
5623

5624
  int insert_interval =
5625
      superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
5626
  if (insert_interval) {
5627
    pThreadInfo->st = taosGetTimestampMs();
H
Hui Li 已提交
5628
  }
5629
  taos_query_a(pThreadInfo->taos, "show databases", callBack, pThreadInfo);
5630

5631
  tsem_wait(&(pThreadInfo->lock_sem));
H
Hui Li 已提交
5632 5633 5634 5635

  return NULL;
}

5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661
static int convertHostToServAddr(char *host, uint16_t port, struct sockaddr_in *serv_addr)
{
  uint16_t rest_port = port + TSDB_PORT_HTTP;
  struct hostent *server = gethostbyname(host);
  if ((server == NULL) || (server->h_addr == NULL)) {
    errorPrint("%s", "ERROR, no such host");
    return -1;
  }

  debugPrint("h_name: %s\nh_addr=%p\nh_addretype: %s\nh_length: %d\n",
            server->h_name,
            server->h_addr,
            (server->h_addrtype == AF_INET)?"ipv4":"ipv6",
            server->h_length);

  memset(serv_addr, 0, sizeof(struct sockaddr_in));
  serv_addr->sin_family = AF_INET;
  serv_addr->sin_port = htons(rest_port);
#ifdef WINDOWS
  serv_addr->sin_addr.s_addr = inet_addr(host);
#else
  memcpy(&(serv_addr->sin_addr.s_addr), server->h_addr, server->h_length);
#endif
  return 0;
}

5662 5663
static void startMultiThreadInsertData(int threads, char* db_name,
        char* precision,SSuperTable* superTblInfo) {
5664

5665 5666
  pthread_t *pids = malloc(threads * sizeof(pthread_t));
  assert(pids != NULL);
H
Hui Li 已提交
5667

5668 5669
  threadInfo *infos = malloc(threads * sizeof(threadInfo));
  assert(infos != NULL);
5670

5671 5672
  memset(pids, 0, threads * sizeof(pthread_t));
  memset(infos, 0, threads * sizeof(threadInfo));
5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689

  //TAOS* taos;
  //if (0 == strncasecmp(superTblInfo->insertMode, "taosc", 5)) {
  //  taos = taos_connect(g_Dbs.host, g_Dbs.user, g_Dbs.password, db_name, g_Dbs.port);
  //  if (NULL == taos) {
  //    printf("connect to server fail, reason: %s\n", taos_errstr(NULL));
  //    exit(-1);
  //  }
  //}

  int32_t timePrec = TSDB_TIME_PRECISION_MILLI;
  if (0 != precision[0]) {
    if (0 == strncasecmp(precision, "ms", 2)) {
      timePrec = TSDB_TIME_PRECISION_MILLI;
    }  else if (0 == strncasecmp(precision, "us", 2)) {
      timePrec = TSDB_TIME_PRECISION_MICRO;
    }  else {
5690
      errorPrint("Not support precision: %s\n", precision);
5691 5692 5693 5694
      exit(-1);
    }
  }

5695
  int64_t start_time;
5696 5697 5698
  if (superTblInfo) {
    if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) {
        start_time = taosGetTimestamp(timePrec);
5699
    } else {
5700 5701 5702 5703 5704
      if (TSDB_CODE_SUCCESS != taosParseTime(
        superTblInfo->startTimestamp,
        &start_time,
        strlen(superTblInfo->startTimestamp),
        timePrec, 0)) {
5705
          ERROR_EXIT("failed to parse time!\n");
5706
      }
5707
    }
5708 5709
  } else {
     start_time = 1500000000000;
5710 5711
  }

5712
  int64_t start = taosGetTimestampMs();
5713

5714
  // read sample data from file first
5715
  if ((superTblInfo) && (0 == strncasecmp(superTblInfo->dataSource,
5716
              "sample", strlen("sample")))) {
5717
    if (0 != prepareSampleDataForSTable(superTblInfo)) {
5718 5719
      errorPrint("%s() LN%d, prepare sample data for stable failed!\n",
              __func__, __LINE__);
5720 5721 5722 5723
      exit(-1);
    }
  }

5724
  // read sample data from file first
5725
  if ((superTblInfo) && (0 == strncasecmp(superTblInfo->dataSource,
5726 5727
              "sample", strlen("sample")))) {
    if (0 != prepareSampleDataForSTable(superTblInfo)) {
5728 5729
      errorPrint("%s() LN%d, prepare sample data for stable failed!\n",
              __func__, __LINE__);
5730 5731 5732 5733 5734 5735 5736 5737
      exit(-1);
    }
  }

  TAOS* taos = taos_connect(
              g_Dbs.host, g_Dbs.user,
              g_Dbs.password, db_name, g_Dbs.port);
  if (NULL == taos) {
5738 5739
    errorPrint("%s() LN%d, connect to server fail , reason: %s\n",
                __func__, __LINE__, taos_errstr(NULL));
5740 5741 5742
    exit(-1);
  }

5743
  int64_t ntables = 0;
5744
  uint64_t startFrom;
5745

5746
  if (superTblInfo) {
5747 5748
    int64_t limit;
    uint64_t offset;
5749

5750
    if ((NULL != g_args.sqlFile) && (superTblInfo->childTblExists == TBL_NO_EXISTS) &&
5751
            ((superTblInfo->childTblOffset != 0) || (superTblInfo->childTblLimit >= 0))) {
5752
      printf("WARNING: offset and limit will not be used since the child tables not exists!\n");
5753 5754
    }

5755
    if (superTblInfo->childTblExists == TBL_ALREADY_EXISTS) {
5756 5757
      if ((superTblInfo->childTblLimit < 0)
          || ((superTblInfo->childTblOffset + superTblInfo->childTblLimit)
5758
            > (superTblInfo->childTblCount))) {
5759 5760 5761 5762 5763 5764
        superTblInfo->childTblLimit =
            superTblInfo->childTblCount - superTblInfo->childTblOffset;
      }

      offset = superTblInfo->childTblOffset;
      limit = superTblInfo->childTblLimit;
5765
    } else {
5766 5767
      limit = superTblInfo->childTblCount;
      offset = 0;
5768 5769
    }

5770 5771 5772
    ntables = limit;
    startFrom = offset;

5773 5774 5775 5776
    if ((superTblInfo->childTblExists != TBL_NO_EXISTS)
        && ((superTblInfo->childTblOffset + superTblInfo->childTblLimit )
            > superTblInfo->childTblCount)) {
      printf("WARNING: specified offset + limit > child table count!\n");
5777
      prompt();
5778 5779 5780 5781 5782
    }

    if ((superTblInfo->childTblExists != TBL_NO_EXISTS)
            && (0 == superTblInfo->childTblLimit)) {
      printf("WARNING: specified limit = 0, which cannot find table name to insert or query! \n");
5783
      prompt();
5784 5785
    }

5786 5787 5788
    superTblInfo->childTblName = (char*)calloc(1,
        limit * TSDB_TABLE_NAME_LEN);
    if (superTblInfo->childTblName == NULL) {
5789
      errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__);
5790 5791 5792 5793
      taos_close(taos);
      exit(-1);
    }

5794
    int64_t childTblCount;
5795 5796 5797 5798 5799 5800
    getChildNameOfSuperTableWithLimitAndOffset(
        taos,
        db_name, superTblInfo->sTblName,
        &superTblInfo->childTblName, &childTblCount,
        limit,
        offset);
5801 5802 5803
  } else {
    ntables = g_args.num_of_tables;
    startFrom = 0;
5804
  }
5805

5806 5807
  taos_close(taos);

5808
  int64_t a = ntables / threads;
5809 5810 5811 5812 5813
  if (a < 1) {
    threads = ntables;
    a = 1;
  }

5814
  int64_t b = 0;
5815 5816 5817 5818
  if (threads != 0) {
    b = ntables % threads;
  }

5819 5820 5821 5822 5823 5824
  if ((superTblInfo)
      && (0 == strncasecmp(superTblInfo->insertMode, "rest", strlen("rest")))) {
    if (convertHostToServAddr(g_Dbs.host, g_Dbs.port, &(g_Dbs.serv_addr)) != 0)
      exit(-1);
  }

H
Hui Li 已提交
5825
  for (int i = 0; i < threads; i++) {
5826
    threadInfo *t_info = infos + i;
H
Hui Li 已提交
5827 5828
    t_info->threadID = i;
    tstrncpy(t_info->db_name, db_name, MAX_DB_NAME_SIZE);
5829
    t_info->time_precision = timePrec;
5830 5831 5832
    t_info->superTblInfo = superTblInfo;

    t_info->start_time = start_time;
5833
    t_info->minDelay = UINT64_MAX;
5834

5835 5836
    if ((NULL == superTblInfo) ||
            (0 == strncasecmp(superTblInfo->insertMode, "taosc", 5))) {
5837
      //t_info->taos = taos;
5838
      t_info->taos = taos_connect(
5839
              g_Dbs.host, g_Dbs.user,
5840
              g_Dbs.password, db_name, g_Dbs.port);
5841
      if (NULL == t_info->taos) {
5842 5843
        errorPrint(
                "connect to server fail from insert sub thread, reason: %s\n",
5844
                taos_errstr(NULL));
5845 5846 5847 5848 5849 5850
        exit(-1);
      }
    } else {
      t_info->taos = NULL;
    }

5851
/*    if ((NULL == superTblInfo)
5852
            || (0 == superTblInfo->multiThreadWriteOneTbl)) {
5853
            */
5854 5855 5856 5857
      t_info->start_table_from = startFrom;
      t_info->ntables = i<b?a+1:a;
      t_info->end_table_to = i < b ? startFrom + a : startFrom + a - 1;
      startFrom = t_info->end_table_to + 1;
5858
/*    } else {
5859 5860
      t_info->start_table_from = 0;
      t_info->ntables = superTblInfo->childTblCount;
5861 5862
      t_info->start_time = t_info->start_time + rand_int() % 10000 - rand_tinyint();
    }
5863
*/
5864
    tsem_init(&(t_info->lock_sem), 0, 0);
5865
    if (ASYNC_MODE == g_Dbs.asyncMode) {
5866
      pthread_create(pids + i, NULL, asyncWrite, t_info);
5867 5868
    } else {
      pthread_create(pids + i, NULL, syncWrite, t_info);
5869
    }
H
Hui Li 已提交
5870
  }
5871

H
Hui Li 已提交
5872 5873 5874 5875
  for (int i = 0; i < threads; i++) {
    pthread_join(pids[i], NULL);
  }

5876 5877 5878 5879
  uint64_t totalDelay = 0;
  uint64_t maxDelay = 0;
  uint64_t minDelay = UINT64_MAX;
  uint64_t cntDelay = 1;
5880 5881
  double  avgDelay = 0;

H
Hui Li 已提交
5882
  for (int i = 0; i < threads; i++) {
5883 5884
    threadInfo *t_info = infos + i;

S
TD-1057  
Shengliang Guan 已提交
5885
    tsem_destroy(&(t_info->lock_sem));
5886 5887
    taos_close(t_info->taos);

5888
    debugPrint("%s() LN%d, [%d] totalInsert=%"PRIu64" totalAffected=%"PRIu64"\n",
5889 5890 5891
            __func__, __LINE__,
            t_info->threadID, t_info->totalInsertRows,
            t_info->totalAffectedRows);
5892 5893
    if (superTblInfo) {
        superTblInfo->totalAffectedRows += t_info->totalAffectedRows;
5894
        superTblInfo->totalInsertRows += t_info->totalInsertRows;
5895 5896 5897
    } else {
        g_args.totalAffectedRows += t_info->totalAffectedRows;
        g_args.totalInsertRows += t_info->totalInsertRows;
5898
    }
5899 5900 5901 5902

    totalDelay  += t_info->totalDelay;
    cntDelay   += t_info->cntDelay;
    if (t_info->maxDelay > maxDelay) maxDelay = t_info->maxDelay;
5903
    if (t_info->minDelay < minDelay) minDelay = t_info->minDelay;
H
Hui Li 已提交
5904
  }
5905
  cntDelay -= 1;
H
Hui Li 已提交
5906

5907
  if (cntDelay == 0)    cntDelay = 1;
5908 5909
  avgDelay = (double)totalDelay / cntDelay;

5910 5911
  int64_t end = taosGetTimestampMs();
  int64_t t = end - start;
5912 5913

  if (superTblInfo) {
5914
    fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n",
5915
          t / 1000.0, superTblInfo->totalInsertRows,
5916 5917
          superTblInfo->totalAffectedRows,
          threads, db_name, superTblInfo->sTblName,
5918
          (double)superTblInfo->totalInsertRows / (t / 1000.0));
5919 5920 5921 5922

    if (g_fpOfInsertResult) {
      fprintf(g_fpOfInsertResult,
          "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n",
5923
          t / 1000.0, superTblInfo->totalInsertRows,
5924 5925
          superTblInfo->totalAffectedRows,
          threads, db_name, superTblInfo->sTblName,
5926
          (double)superTblInfo->totalInsertRows / (t / 1000.0));
5927
    }
5928
  } else {
5929
    fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s %.2f records/second\n\n",
5930
          t / 1000.0, g_args.totalInsertRows,
5931 5932
          g_args.totalAffectedRows,
          threads, db_name,
5933
          (double)g_args.totalInsertRows / (t / 1000.0));
5934 5935 5936
    if (g_fpOfInsertResult) {
      fprintf(g_fpOfInsertResult,
          "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s %.2f records/second\n\n",
5937
          t * 1000.0, g_args.totalInsertRows,
5938 5939
          g_args.totalAffectedRows,
          threads, db_name,
5940
          (double)g_args.totalInsertRows / (t / 1000.0));
5941
    }
5942
  }
5943

5944
  fprintf(stderr, "insert delay, avg: %10.2fms, max: %"PRIu64"ms, min: %"PRIu64"ms\n\n",
5945
          avgDelay, maxDelay, minDelay);
5946 5947
  if (g_fpOfInsertResult) {
    fprintf(g_fpOfInsertResult, "insert delay, avg:%10.2fms, max: %"PRIu64"ms, min: %"PRIu64"ms\n\n",
5948
          avgDelay, maxDelay, minDelay);
5949
  }
5950

5951 5952
  //taos_close(taos);

H
Hui Li 已提交
5953
  free(pids);
5954
  free(infos);
H
Hui Li 已提交
5955 5956
}

5957
static void *readTable(void *sarg) {
5958
#if 1
5959
  threadInfo *rinfo = (threadInfo *)sarg;
H
hzcheng 已提交
5960 5961
  TAOS *taos = rinfo->taos;
  char command[BUFFER_SIZE] = "\0";
5962
  uint64_t sTime = rinfo->start_time;
H
hzcheng 已提交
5963 5964
  char *tb_prefix = rinfo->tb_prefix;
  FILE *fp = fopen(rinfo->fp, "a");
H
Hui Li 已提交
5965
  if (NULL == fp) {
5966
    errorPrint( "fopen %s fail, reason:%s.\n", rinfo->fp, strerror(errno));
H
Hui Li 已提交
5967 5968
    return NULL;
  }
5969

5970
  int64_t num_of_DPT;
5971
/*  if (rinfo->superTblInfo) {
5972 5973
    num_of_DPT = rinfo->superTblInfo->insertRows; //  nrecords_per_table;
  } else {
5974
  */
5975
      num_of_DPT = g_args.num_of_DPT;
5976
//  }
5977

5978 5979
  int64_t num_of_tables = rinfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1;
  int64_t totalData = num_of_DPT * num_of_tables;
5980
  bool do_aggreFunc = g_Dbs.do_aggreFunc;
H
hzcheng 已提交
5981 5982 5983 5984 5985

  int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2;
  if (!do_aggreFunc) {
    printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n");
  }
5986
  printf("%"PRId64" records:\n", totalData);
H
hzcheng 已提交
5987 5988
  fprintf(fp, "| QFunctions |    QRecords    |   QSpeed(R/s)   |  QLatency(ms) |\n");

5989
  for (int j = 0; j < n; j++) {
H
hzcheng 已提交
5990
    double totalT = 0;
5991
    uint64_t count = 0;
5992 5993
    for (int64_t i = 0; i < num_of_tables; i++) {
      sprintf(command, "select %s from %s%"PRId64" where ts>= %" PRIu64,
5994
              aggreFunc[j], tb_prefix, i, sTime);
H
hzcheng 已提交
5995

5996
      double t = taosGetTimestampMs();
S
Shuaiqiang Chang 已提交
5997 5998
      TAOS_RES *pSql = taos_query(taos, command);
      int32_t code = taos_errno(pSql);
H
hzcheng 已提交
5999

S
Shuaiqiang Chang 已提交
6000
      if (code != 0) {
6001
        errorPrint( "Failed to query:%s\n", taos_errstr(pSql));
S
Shuaiqiang Chang 已提交
6002
        taos_free_result(pSql);
H
hzcheng 已提交
6003
        taos_close(taos);
6004
        fclose(fp);
6005
        return NULL;
H
hzcheng 已提交
6006 6007
      }

6008
      while(taos_fetch_row(pSql) != NULL) {
H
hzcheng 已提交
6009 6010 6011
        count++;
      }

6012
      t = taosGetTimestampMs() - t;
H
hzcheng 已提交
6013 6014
      totalT += t;

S
Shuaiqiang Chang 已提交
6015
      taos_free_result(pSql);
H
hzcheng 已提交
6016 6017
    }

6018
    fprintf(fp, "|%10s  |   %"PRId64"   |  %12.2f   |   %10.2f  |\n",
S
slguan 已提交
6019
            aggreFunc[j][0] == '*' ? "   *   " : aggreFunc[j], totalData,
H
hzcheng 已提交
6020
            (double)(num_of_tables * num_of_DPT) / totalT, totalT * 1000);
6021
    printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT * 1000);
H
hzcheng 已提交
6022 6023 6024
  }
  fprintf(fp, "\n");
  fclose(fp);
6025
#endif
H
hzcheng 已提交
6026 6027 6028
  return NULL;
}

6029
static void *readMetric(void *sarg) {
6030
#if 1
6031
  threadInfo *rinfo = (threadInfo *)sarg;
H
hzcheng 已提交
6032 6033 6034
  TAOS *taos = rinfo->taos;
  char command[BUFFER_SIZE] = "\0";
  FILE *fp = fopen(rinfo->fp, "a");
H
Hui Li 已提交
6035 6036 6037 6038
  if (NULL == fp) {
    printf("fopen %s fail, reason:%s.\n", rinfo->fp, strerror(errno));
    return NULL;
  }
6039

6040 6041 6042
  int64_t num_of_DPT = rinfo->superTblInfo->insertRows;
  int64_t num_of_tables = rinfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1;
  int64_t totalData = num_of_DPT * num_of_tables;
6043
  bool do_aggreFunc = g_Dbs.do_aggreFunc;
H
hzcheng 已提交
6044 6045 6046 6047 6048

  int n = do_aggreFunc ? (sizeof(aggreFunc) / sizeof(aggreFunc[0])) : 2;
  if (!do_aggreFunc) {
    printf("\nThe first field is either Binary or Bool. Aggregation functions are not supported.\n");
  }
6049 6050
  printf("%"PRId64" records:\n", totalData);
  fprintf(fp, "Querying On %"PRId64" records:\n", totalData);
H
hzcheng 已提交
6051 6052

  for (int j = 0; j < n; j++) {
6053
    char condition[COND_BUF_LEN] = "\0";
B
Bomin Zhang 已提交
6054
    char tempS[64] = "\0";
H
hzcheng 已提交
6055

6056
    int64_t m = 10 < num_of_tables ? 10 : num_of_tables;
H
hzcheng 已提交
6057

6058
    for (int64_t i = 1; i <= m; i++) {
H
hzcheng 已提交
6059
      if (i == 1) {
6060
        sprintf(tempS, "t1 = %"PRId64"", i);
H
hzcheng 已提交
6061
      } else {
6062
        sprintf(tempS, " or t1 = %"PRId64" ", i);
H
hzcheng 已提交
6063
      }
6064
      strncat(condition, tempS, COND_BUF_LEN - 1);
H
hzcheng 已提交
6065

L
liu0x54 已提交
6066
      sprintf(command, "select %s from meters where %s", aggreFunc[j], condition);
H
hzcheng 已提交
6067 6068 6069 6070

      printf("Where condition: %s\n", condition);
      fprintf(fp, "%s\n", command);

6071
      double t = taosGetTimestampMs();
H
hzcheng 已提交
6072

S
Shuaiqiang Chang 已提交
6073 6074 6075 6076
      TAOS_RES *pSql = taos_query(taos, command);
      int32_t code = taos_errno(pSql);

      if (code != 0) {
6077
        errorPrint( "Failed to query:%s\n", taos_errstr(pSql));
S
Shuaiqiang Chang 已提交
6078
        taos_free_result(pSql);
H
hzcheng 已提交
6079
        taos_close(taos);
6080
        fclose(fp);
6081
        return NULL;
H
hzcheng 已提交
6082 6083
      }
      int count = 0;
6084
      while(taos_fetch_row(pSql) != NULL) {
H
hzcheng 已提交
6085 6086
        count++;
      }
6087
      t = taosGetTimestampMs() - t;
H
hzcheng 已提交
6088

6089
      fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n",
6090 6091
              num_of_tables * num_of_DPT / (t * 1000.0), t);
      printf("select %10s took %.6f second(s)\n\n", aggreFunc[j], t * 1000.0);
H
hzcheng 已提交
6092

S
Shuaiqiang Chang 已提交
6093
      taos_free_result(pSql);
H
hzcheng 已提交
6094 6095 6096 6097
    }
    fprintf(fp, "\n");
  }
  fclose(fp);
6098
#endif
H
hzcheng 已提交
6099 6100 6101
  return NULL;
}

6102 6103 6104
static void prompt()
{
  if (!g_args.answer_yes) {
6105
    printf("         Press enter key to continue or Ctrl-C to stop\n\n");
6106 6107 6108 6109
    (void)getchar();
  }
}

6110
static int insertTestProcess() {
6111

6112 6113 6114
  setupForAnsiEscape();
  int ret = printfInsertMeta();
  resetAfterAnsiEscape();
6115

6116 6117 6118
  if (ret == -1)
    exit(EXIT_FAILURE);

6119
  debugPrint("%d result file: %s\n", __LINE__, g_Dbs.resultFile);
6120 6121
  g_fpOfInsertResult = fopen(g_Dbs.resultFile, "a");
  if (NULL == g_fpOfInsertResult) {
6122
    errorPrint( "Failed to open %s for save result\n", g_Dbs.resultFile);
6123 6124
    return -1;
  }
6125

6126 6127
  if (g_fpOfInsertResult)
    printfInsertMetaToFile(g_fpOfInsertResult);
6128

6129
  prompt();
6130

6131 6132 6133
  init_rand_data();

  // create database and super tables
6134
  if(createDatabasesAndStables() != 0) {
6135 6136
    if (g_fpOfInsertResult)
      fclose(g_fpOfInsertResult);
6137 6138
    return -1;
  }
6139 6140

  // pretreatement
6141
  prepareSampleData();
6142

6143 6144 6145 6146
  double start;
  double end;

  // create child tables
6147
  start = taosGetTimestampMs();
6148
  createChildTables();
6149
  end = taosGetTimestampMs();
6150

6151
  if (g_totalChildTables > 0) {
6152
    fprintf(stderr, "Spent %.4f seconds to create %"PRId64" tables with %d thread(s)\n\n",
6153
            (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl);
6154 6155
    if (g_fpOfInsertResult) {
      fprintf(g_fpOfInsertResult,
6156
            "Spent %.4f seconds to create %"PRId64" tables with %d thread(s)\n\n",
6157
            (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl);
6158
    }
6159
  }
6160

6161
  taosMsleep(1000);
6162
  // create sub threads for inserting data
6163
  //start = taosGetTimestampMs();
6164
  for (int i = 0; i < g_Dbs.dbCount; i++) {
6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177
    if (g_Dbs.use_metric) {
      if (g_Dbs.db[i].superTblCount > 0) {
        for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {

          SSuperTable* superTblInfo = &g_Dbs.db[i].superTbls[j];

          if (superTblInfo && (superTblInfo->insertRows > 0)) {
            startMultiThreadInsertData(
              g_Dbs.threadCount,
              g_Dbs.db[i].dbName,
              g_Dbs.db[i].dbCfg.precision,
              superTblInfo);
          }
6178
        }
6179
      }
6180 6181
    } else {
        startMultiThreadInsertData(
6182 6183 6184
          g_Dbs.threadCount,
          g_Dbs.db[i].dbName,
          g_Dbs.db[i].dbCfg.precision,
6185
          NULL);
H
Hui Li 已提交
6186
    }
6187
  }
6188
  //end = taosGetTimestampMs();
6189

6190
  //int64_t    totalInsertRows = 0;
6191
  //int64_t    totalAffectedRows = 0;
6192
  //for (int i = 0; i < g_Dbs.dbCount; i++) {
6193
  //  for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
6194
  //  totalInsertRows+= g_Dbs.db[i].superTbls[j].totalInsertRows;
6195 6196
  //  totalAffectedRows += g_Dbs.db[i].superTbls[j].totalAffectedRows;
  //}
6197
  //printf("Spent %.4f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s)\n\n", end - start, totalInsertRows, totalAffectedRows, g_Dbs.threadCount);
6198
  postFreeResource();
6199

6200 6201 6202
  return 0;
}

6203 6204
static void *specifiedTableQuery(void *sarg) {
  threadInfo *pThreadInfo = (threadInfo *)sarg;
6205

6206
  if (pThreadInfo->taos == NULL) {
6207 6208 6209 6210 6211 6212 6213 6214
    TAOS * taos = NULL;
    taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          NULL,
          g_queryInfo.port);
    if (taos == NULL) {
      errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
6215
            pThreadInfo->threadID, taos_errstr(NULL));
6216 6217
      return NULL;
    } else {
6218
      pThreadInfo->taos = taos;
6219 6220 6221
    }
  }

6222 6223
  char sqlStr[MAX_DB_NAME_SIZE + 5];
  sprintf(sqlStr, "use %s", g_queryInfo.dbName);
6224 6225
  if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
    taos_close(pThreadInfo->taos);
6226 6227 6228 6229
    errorPrint( "use database %s failed!\n\n",
                g_queryInfo.dbName);
    return NULL;
  }
6230

6231 6232
  uint64_t st = 0;
  uint64_t et = 0;
6233

6234
  uint64_t queryTimes = g_queryInfo.specifiedQueryInfo.queryTimes;
6235

6236 6237 6238
  uint64_t totalQueried = 0;
  uint64_t lastPrintTime = taosGetTimestampMs();
  uint64_t startTs = taosGetTimestampMs();
6239

6240 6241 6242 6243 6244 6245
  if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
        sprintf(pThreadInfo->fp, "%s-%d",
                g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
                pThreadInfo->threadID);
  }

6246
  while(queryTimes --) {
6247 6248 6249
    if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) <
            (int64_t)g_queryInfo.specifiedQueryInfo.queryInterval) {
      taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval - (et - st)); // ms
6250 6251
    }

6252 6253 6254
    st = taosGetTimestampMs();

    selectAndGetResult(pThreadInfo,
6255
          g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq]);
6256

6257 6258 6259 6260
    et = taosGetTimestampMs();
    printf("=thread[%"PRId64"] use %s complete one sql, Spent %10.3f s\n",
              taosGetSelfPthreadId(), g_queryInfo.queryMode, (et - st)/1000.0);

6261 6262
    totalQueried ++;
    g_queryInfo.specifiedQueryInfo.totalQueried ++;
6263

6264 6265
    uint64_t  currentPrintTime = taosGetTimestampMs();
    uint64_t  endTs = taosGetTimestampMs();
6266
    if (currentPrintTime - lastPrintTime > 30*1000) {
6267
      debugPrint("%s() LN%d, endTs=%"PRIu64"ms, startTs=%"PRIu64"ms\n",
6268
          __func__, __LINE__, endTs, startTs);
6269
      printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.6f\n",
6270 6271
                    pThreadInfo->threadID,
                    totalQueried,
6272
                    (double)(totalQueried/((endTs-startTs)/1000.0)));
6273
      lastPrintTime = currentPrintTime;
6274
    }
H
Hui Li 已提交
6275
  }
6276 6277
  return NULL;
}
H
Hui Li 已提交
6278

6279
static void replaceChildTblName(char* inSql, char* outSql, int tblIndex) {
6280 6281
  char sourceString[32] = "xxxx";
  char subTblName[MAX_TB_NAME_SIZE*3];
6282 6283
  sprintf(subTblName, "%s.%s",
          g_queryInfo.dbName,
6284
          g_queryInfo.superQueryInfo.childTblName + tblIndex*TSDB_TABLE_NAME_LEN);
6285 6286

  //printf("inSql: %s\n", inSql);
6287

6288 6289
  char* pos = strstr(inSql, sourceString);
  if (0 == pos) {
6290
    return;
H
Hui Li 已提交
6291
  }
6292

6293
  tstrncpy(outSql, inSql, pos - inSql + 1);
6294
  //printf("1: %s\n", outSql);
6295
  strncat(outSql, subTblName, MAX_QUERY_SQL_LENGTH - 1);
6296
  //printf("2: %s\n", outSql);
6297
  strncat(outSql, pos+strlen(sourceString), MAX_QUERY_SQL_LENGTH - 1);
6298
  //printf("3: %s\n", outSql);
H
Hui Li 已提交
6299 6300
}

6301
static void *superTableQuery(void *sarg) {
6302
  char sqlstr[MAX_QUERY_SQL_LENGTH];
6303
  threadInfo *pThreadInfo = (threadInfo *)sarg;
6304

6305
  if (pThreadInfo->taos == NULL) {
6306 6307 6308 6309 6310 6311 6312 6313
    TAOS * taos = NULL;
    taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          NULL,
          g_queryInfo.port);
    if (taos == NULL) {
      errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
6314
            pThreadInfo->threadID, taos_errstr(NULL));
6315 6316
      return NULL;
    } else {
6317
      pThreadInfo->taos = taos;
6318 6319 6320
    }
  }

6321 6322
  uint64_t st = 0;
  uint64_t et = (int64_t)g_queryInfo.superQueryInfo.queryInterval;
6323

6324 6325 6326
  uint64_t queryTimes = g_queryInfo.superQueryInfo.queryTimes;
  uint64_t totalQueried = 0;
  uint64_t  startTs = taosGetTimestampMs();
6327

6328
  uint64_t  lastPrintTime = taosGetTimestampMs();
6329
  while(queryTimes --) {
6330 6331 6332
    if (g_queryInfo.superQueryInfo.queryInterval
            && (et - st) < (int64_t)g_queryInfo.superQueryInfo.queryInterval) {
      taosMsleep(g_queryInfo.superQueryInfo.queryInterval - (et - st)); // ms
6333
      //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to);
6334
    }
H
Hui Li 已提交
6335

6336
    st = taosGetTimestampMs();
6337
    for (int i = pThreadInfo->start_table_from; i <= pThreadInfo->end_table_to; i++) {
6338
      for (int j = 0; j < g_queryInfo.superQueryInfo.sqlCount; j++) {
6339
        memset(sqlstr,0,sizeof(sqlstr));
6340
        replaceChildTblName(g_queryInfo.superQueryInfo.sql[j], sqlstr, i);
6341
        if (g_queryInfo.superQueryInfo.result[j][0] != 0) {
6342
          sprintf(pThreadInfo->fp, "%s-%d",
6343
                  g_queryInfo.superQueryInfo.result[j],
6344
                  pThreadInfo->threadID);
6345
        }
6346
        selectAndGetResult(pThreadInfo, sqlstr);
6347 6348 6349 6350 6351 6352 6353

        totalQueried++;
        g_queryInfo.superQueryInfo.totalQueried ++;

        int64_t  currentPrintTime = taosGetTimestampMs();
        int64_t  endTs = taosGetTimestampMs();
        if (currentPrintTime - lastPrintTime > 30*1000) {
6354
          printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.3f\n",
6355 6356
                    pThreadInfo->threadID,
                    totalQueried,
6357
                    (double)(totalQueried/((endTs-startTs)/1000.0)));
6358
          lastPrintTime = currentPrintTime;
6359
        }
6360
      }
H
Hui Li 已提交
6361
    }
6362
    et = taosGetTimestampMs();
6363
    printf("####thread[%"PRId64"] complete all sqls to allocate all sub-tables[%"PRIu64" - %"PRIu64"] once queries duration:%.4fs\n\n",
6364
            taosGetSelfPthreadId(),
6365 6366
            pThreadInfo->start_table_from,
            pThreadInfo->end_table_to,
6367
            (double)(et - st)/1000.0);
6368
  }
6369

6370 6371 6372
  return NULL;
}

6373
static int queryTestProcess() {
6374 6375 6376 6377

  setupForAnsiEscape();
  printfQueryMeta();
  resetAfterAnsiEscape();
6378 6379 6380 6381 6382 6383

  TAOS * taos = NULL;
  taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          NULL,
6384
          g_queryInfo.port);
6385
  if (taos == NULL) {
6386 6387
    errorPrint( "Failed to connect to TDengine, reason:%s\n",
            taos_errstr(NULL));
6388 6389 6390
    exit(-1);
  }

6391
  if (0 != g_queryInfo.superQueryInfo.sqlCount) {
6392 6393
    getAllChildNameOfSuperTable(taos,
            g_queryInfo.dbName,
6394 6395 6396
            g_queryInfo.superQueryInfo.sTblName,
            &g_queryInfo.superQueryInfo.childTblName,
            &g_queryInfo.superQueryInfo.childTblCount);
6397
  }
6398

6399
  prompt();
6400

6401 6402 6403
  if (g_args.debug_print || g_args.verbose_print) {
    printfQuerySystemInfo(taos);
  }
6404

6405 6406 6407 6408 6409 6410
  if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) {
    if (convertHostToServAddr(
        g_queryInfo.host, g_queryInfo.port, &g_queryInfo.serv_addr) != 0)
      exit(-1);
  }

6411 6412 6413
  pthread_t  *pids  = NULL;
  threadInfo *infos = NULL;
  //==== create sub threads for query from specify table
6414
  int nConcurrent = g_queryInfo.specifiedQueryInfo.concurrent;
6415
  uint64_t nSqlCount = g_queryInfo.specifiedQueryInfo.sqlCount;
6416

6417
  uint64_t startTs = taosGetTimestampMs();
6418

6419 6420 6421 6422 6423 6424
  if ((nSqlCount > 0) && (nConcurrent > 0)) {

    pids  = malloc(nConcurrent * nSqlCount * sizeof(pthread_t));
    infos = malloc(nConcurrent * nSqlCount * sizeof(threadInfo));

    if ((NULL == pids) || (NULL == infos)) {
6425
      taos_close(taos);
6426
      ERROR_EXIT("memory allocation failed for create threads\n");
6427
    }
6428

6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449
    for (uint64_t i = 0; i < nSqlCount; i++) {
        for (int j = 0; j < nConcurrent; j++) {
            uint64_t seq = i * nConcurrent + j;
            threadInfo *t_info = infos + seq;
            t_info->threadID = seq;
            t_info->querySeq = i;

            if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) {

                char sqlStr[MAX_TB_NAME_SIZE*2];
                sprintf(sqlStr, "use %s", g_queryInfo.dbName);
                verbosePrint("%s() %d sqlStr: %s\n", __func__, __LINE__, sqlStr);
                if (0 != queryDbExec(taos, sqlStr, NO_INSERT_TYPE, false)) {
                    taos_close(taos);
                    free(infos);
                    free(pids);
                    errorPrint( "use database %s failed!\n\n",
                        g_queryInfo.dbName);
                    return -1;
                }
            }
6450

6451
            t_info->taos = NULL;// TODO: workaround to use separate taos connection;
6452

6453 6454 6455
            pthread_create(pids + seq, NULL, specifiedTableQuery,
                t_info);
        }
6456
    }
6457
  } else {
6458
    g_queryInfo.specifiedQueryInfo.concurrent = 0;
6459
  }
6460

6461 6462
  taos_close(taos);

6463 6464 6465
  pthread_t  *pidsOfSub  = NULL;
  threadInfo *infosOfSub = NULL;
  //==== create sub threads for query from all sub table of the super table
6466 6467 6468 6469
  if ((g_queryInfo.superQueryInfo.sqlCount > 0)
          && (g_queryInfo.superQueryInfo.threadCnt > 0)) {
    pidsOfSub  = malloc(g_queryInfo.superQueryInfo.threadCnt * sizeof(pthread_t));
    infosOfSub = malloc(g_queryInfo.superQueryInfo.threadCnt * sizeof(threadInfo));
6470 6471

    if ((NULL == pidsOfSub) || (NULL == infosOfSub)) {
6472 6473
      free(infos);
      free(pids);
6474

6475
      ERROR_EXIT("memory allocation failed for create threads\n");
6476
    }
6477

6478
    int64_t ntables = g_queryInfo.superQueryInfo.childTblCount;
6479
    int threads = g_queryInfo.superQueryInfo.threadCnt;
6480

6481
    int64_t a = ntables / threads;
6482 6483 6484 6485
    if (a < 1) {
      threads = ntables;
      a = 1;
    }
6486

6487
    int64_t b = 0;
6488 6489 6490
    if (threads != 0) {
      b = ntables % threads;
    }
6491

6492
    uint64_t startFrom = 0;
6493
    for (int i = 0; i < threads; i++) {
6494 6495
      threadInfo *t_info = infosOfSub + i;
      t_info->threadID = i;
6496

6497 6498 6499 6500
      t_info->start_table_from = startFrom;
      t_info->ntables = i<b?a+1:a;
      t_info->end_table_to = i < b ? startFrom + a : startFrom + a - 1;
      startFrom = t_info->end_table_to + 1;
6501
      t_info->taos = NULL; // TODO: workaround to use separate taos connection;
6502
      pthread_create(pidsOfSub + i, NULL, superTableQuery, t_info);
6503 6504
    }

6505
    g_queryInfo.superQueryInfo.threadCnt = threads;
6506
  } else {
6507
    g_queryInfo.superQueryInfo.threadCnt = 0;
6508
  }
6509

6510 6511 6512 6513 6514 6515
  if ((nSqlCount > 0) && (nConcurrent > 0)) {
    for (int i = 0; i < nConcurrent; i++) {
      for (int j = 0; j < nSqlCount; j++) {
        pthread_join(pids[i * nSqlCount + j], NULL);
      }
    }
6516
  }
S
Shuaiqiang Chang 已提交
6517

6518
  tmfree((char*)pids);
6519
  tmfree((char*)infos);
6520

6521
  for (int i = 0; i < g_queryInfo.superQueryInfo.threadCnt; i++) {
6522
    pthread_join(pidsOfSub[i], NULL);
H
hzcheng 已提交
6523
  }
H
Hui Li 已提交
6524

6525
  tmfree((char*)pidsOfSub);
6526
  tmfree((char*)infosOfSub);
6527

6528
//  taos_close(taos);// TODO: workaround to use separate taos connection;
6529
  uint64_t endTs = taosGetTimestampMs();
6530

6531
  uint64_t totalQueried = g_queryInfo.specifiedQueryInfo.totalQueried +
6532 6533
    g_queryInfo.superQueryInfo.totalQueried;

6534
  fprintf(stderr, "==== completed total queries: %"PRIu64", the QPS of all threads: %10.3f====\n",
6535
          totalQueried,
6536
          (double)(totalQueried/((endTs-startTs)/1000.0)));
6537 6538 6539
  return 0;
}

6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554
static void stable_sub_callback(
        TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
  if (res == NULL || taos_errno(res) != 0) {
    errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n",
           __func__, __LINE__, code, taos_errstr(res));
    return;
  }

  if (param)
    appendResultToFile(res, ((threadInfo *)param)->fp);
  // tao_unscribe() will free result.
}

static void specified_sub_callback(
        TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
6555
  if (res == NULL || taos_errno(res) != 0) {
6556 6557
    errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n",
           __func__, __LINE__, code, taos_errstr(res));
6558 6559
    return;
  }
6560

6561
  if (param)
6562
    appendResultToFile(res, ((threadInfo *)param)->fp);
6563
  // tao_unscribe() will free result.
H
hzcheng 已提交
6564 6565
}

6566
static TAOS_SUB* subscribeImpl(
6567
        QUERY_CLASS class,
6568
        threadInfo *pThreadInfo,
6569
        char *sql, char* topic, bool restart, uint64_t interval)
6570
{
6571
  TAOS_SUB* tsub = NULL;
H
hzcheng 已提交
6572

6573 6574
  if ((SPECIFIED_CLASS == class)
          && (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode)) {
6575 6576
    tsub = taos_subscribe(
            pThreadInfo->taos,
6577
            restart,
6578
            topic, sql, specified_sub_callback, (void*)pThreadInfo,
6579
            g_queryInfo.specifiedQueryInfo.subscribeInterval);
6580 6581
  } else if ((STABLE_CLASS == class)
          && (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode)) {
6582 6583 6584 6585 6586
    tsub = taos_subscribe(
            pThreadInfo->taos,
            restart,
            topic, sql, stable_sub_callback, (void*)pThreadInfo,
            g_queryInfo.superQueryInfo.subscribeInterval);
6587
  } else {
6588 6589
    tsub = taos_subscribe(
            pThreadInfo->taos,
6590
            restart,
6591
            topic, sql, NULL, NULL, interval);
6592
  }
6593

6594 6595 6596
  if (tsub == NULL) {
    printf("failed to create subscription. topic:%s, sql:%s\n", topic, sql);
    return NULL;
6597
  }
6598

6599 6600
  return tsub;
}
H
hzcheng 已提交
6601

6602 6603
static void *superSubscribe(void *sarg) {
  threadInfo *pThreadInfo = (threadInfo *)sarg;
6604
  char subSqlstr[MAX_QUERY_SQL_LENGTH];
6605
  TAOS_SUB*    tsub[MAX_QUERY_SQL_COUNT] = {0};
6606
  uint64_t tsubSeq;
H
hzcheng 已提交
6607

6608 6609
  if (pThreadInfo->ntables > MAX_QUERY_SQL_COUNT) {
      errorPrint("The table number(%"PRId64") of the thread is more than max query sql count: %d\n",
6610 6611 6612 6613 6614
              pThreadInfo->ntables,
              MAX_QUERY_SQL_COUNT);
      exit(-1);
  }

6615
  if (pThreadInfo->taos == NULL) {
6616 6617 6618 6619 6620 6621 6622 6623
    TAOS * taos = NULL;
    taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          g_queryInfo.dbName,
          g_queryInfo.port);
    if (taos == NULL) {
      errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
6624
            pThreadInfo->threadID, taos_errstr(NULL));
6625 6626
      return NULL;
    } else {
6627
      pThreadInfo->taos = taos;
6628 6629 6630
    }
  }

6631 6632
  char sqlStr[MAX_TB_NAME_SIZE*2];
  sprintf(sqlStr, "use %s", g_queryInfo.dbName);
6633 6634
  if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
    taos_close(pThreadInfo->taos);
6635 6636
    errorPrint( "use database %s failed!\n\n",
                g_queryInfo.dbName);
6637 6638
    return NULL;
  }
6639

6640 6641 6642
  char topic[32] = {0};
  for (uint64_t i = pThreadInfo->start_table_from;
          i <= pThreadInfo->end_table_to; i++) {
6643 6644

      tsubSeq = i - pThreadInfo->start_table_from;
6645 6646 6647 6648 6649
      verbosePrint("%s() LN%d, [%d], start=%"PRId64" end=%"PRId64" i=%"PRIu64"\n",
              __func__, __LINE__,
              pThreadInfo->threadID,
              pThreadInfo->start_table_from,
              pThreadInfo->end_table_to, i);
6650 6651
      sprintf(topic, "taosdemo-subscribe-%"PRIu64"-%"PRIu64"",
              i, pThreadInfo->querySeq);
6652
      memset(subSqlstr, 0, sizeof(subSqlstr));
6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663
      replaceChildTblName(
              g_queryInfo.superQueryInfo.sql[pThreadInfo->querySeq],
              subSqlstr, i);
      if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
        sprintf(pThreadInfo->fp, "%s-%d",
                g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq],
                pThreadInfo->threadID);
      }

      debugPrint("%s() LN%d, [%d] subSqlstr: %s\n",
              __func__, __LINE__, pThreadInfo->threadID, subSqlstr);
6664
      tsub[tsubSeq] = subscribeImpl(
6665
              STABLE_CLASS,
6666
              pThreadInfo, subSqlstr, topic,
6667 6668
              g_queryInfo.superQueryInfo.subscribeRestart,
              g_queryInfo.superQueryInfo.subscribeInterval);
6669
      if (NULL == tsub[tsubSeq]) {
6670
        taos_close(pThreadInfo->taos);
6671 6672
        return NULL;
      }
6673
  }
6674 6675

  // start loop to consume result
6676 6677 6678 6679
  int consumed[MAX_QUERY_SQL_COUNT];
  for (int i = 0; i < MAX_QUERY_SQL_COUNT; i++) {
    consumed[i] = 0;
  }
6680
  TAOS_RES* res = NULL;
6681

6682 6683
  uint64_t st = 0, et = 0;

6684
  while(1) {
6685 6686
    for (uint64_t i = pThreadInfo->start_table_from;
            i <= pThreadInfo->end_table_to; i++) {
6687 6688 6689 6690
      tsubSeq = i - pThreadInfo->start_table_from;
      if (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode) {
          continue;
      }
6691

6692 6693
      st = taosGetTimestampMs();
      performancePrint("st: %"PRIu64" et: %"PRIu64" st-et: %"PRIu64"\n", st, et, (st - et));
6694
      res = taos_consume(tsub[tsubSeq]);
6695 6696 6697
      et = taosGetTimestampMs();
      performancePrint("st: %"PRIu64" et: %"PRIu64" delta: %"PRIu64"\n", st, et, (et - st));

6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714
      if (res) {
          if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
              sprintf(pThreadInfo->fp, "%s-%d",
                      g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq],
                      pThreadInfo->threadID);
              appendResultToFile(res, pThreadInfo->fp);
          }
          if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
              sprintf(pThreadInfo->fp, "%s-%d",
                      g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq],
                      pThreadInfo->threadID);
              appendResultToFile(res, pThreadInfo->fp);
          }
          consumed[tsubSeq] ++;

          if ((g_queryInfo.superQueryInfo.subscribeKeepProgress)
                  && (consumed[tsubSeq] >=
6715
                      g_queryInfo.superQueryInfo.resubAfterConsume)) {
6716 6717 6718 6719
              printf("keepProgress:%d, resub super table query: %"PRIu64"\n",
                      g_queryInfo.superQueryInfo.subscribeKeepProgress,
                      pThreadInfo->querySeq);
              taos_unsubscribe(tsub[tsubSeq],
6720
                    g_queryInfo.superQueryInfo.subscribeKeepProgress);
6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733
              consumed[tsubSeq]= 0;
              tsub[tsubSeq] = subscribeImpl(
                      STABLE_CLASS,
                      pThreadInfo, subSqlstr, topic,
                      g_queryInfo.superQueryInfo.subscribeRestart,
                      g_queryInfo.superQueryInfo.subscribeInterval
                      );
              if (NULL == tsub[tsubSeq]) {
                  taos_close(pThreadInfo->taos);
                  return NULL;
              }
          }
      }
H
hzcheng 已提交
6734 6735
    }
  }
6736
  taos_free_result(res);
6737

6738 6739
  for (uint64_t i = pThreadInfo->start_table_from;
          i <= pThreadInfo->end_table_to; i++) {
6740 6741
    tsubSeq = i - pThreadInfo->start_table_from;
    taos_unsubscribe(tsub[tsubSeq], 0);
6742
  }
6743

6744
  taos_close(pThreadInfo->taos);
H
hzcheng 已提交
6745 6746 6747
  return NULL;
}

6748 6749
static void *specifiedSubscribe(void *sarg) {
  threadInfo *pThreadInfo = (threadInfo *)sarg;
6750
  TAOS_SUB*  tsub = NULL;
6751

6752
  if (pThreadInfo->taos == NULL) {
6753 6754 6755 6756 6757 6758 6759 6760
    TAOS * taos = NULL;
    taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          g_queryInfo.dbName,
          g_queryInfo.port);
    if (taos == NULL) {
      errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
6761
            pThreadInfo->threadID, taos_errstr(NULL));
6762 6763
      return NULL;
    } else {
6764
      pThreadInfo->taos = taos;
6765 6766 6767
    }
  }

6768 6769
  char sqlStr[MAX_TB_NAME_SIZE*2];
  sprintf(sqlStr, "use %s", g_queryInfo.dbName);
6770
  debugPrint("%s() %d sqlStr: %s\n", __func__, __LINE__, sqlStr);
6771 6772
  if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
    taos_close(pThreadInfo->taos);
6773 6774
    return NULL;
  }
6775

6776
  char topic[32] = {0};
6777 6778 6779 6780
  sprintf(topic, "taosdemo-subscribe-%"PRIu64"", pThreadInfo->querySeq);
  if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
      sprintf(pThreadInfo->fp, "%s-%d",
                g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
6781
                pThreadInfo->threadID);
6782
  }
6783 6784
  tsub = subscribeImpl(
                      SPECIFIED_CLASS, pThreadInfo,
6785 6786
          g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
          topic,
6787 6788
          g_queryInfo.specifiedQueryInfo.subscribeRestart,
          g_queryInfo.specifiedQueryInfo.subscribeInterval);
6789 6790 6791
  if (NULL == tsub) {
      taos_close(pThreadInfo->taos);
      return NULL;
6792
  }
6793

6794 6795
  // start loop to consume result
  TAOS_RES* res = NULL;
6796

6797
  int consumed;
6798

6799
  while(1) {
6800
      if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) {
6801 6802
        continue;
      }
6803

6804
      res = taos_consume(tsub);
6805
      if (res) {
6806 6807 6808 6809 6810 6811 6812
          if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
              sprintf(pThreadInfo->fp, "%s-%d",
                      g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
                      pThreadInfo->threadID);
              appendResultToFile(res, pThreadInfo->fp);
          }

6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823
          consumed ++;
          if ((g_queryInfo.specifiedQueryInfo.subscribeKeepProgress)
                && (consumed >=
                    g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq])) {
              printf("keepProgress:%d, resub specified query: %"PRIu64"\n",
                    g_queryInfo.specifiedQueryInfo.subscribeKeepProgress,
                    pThreadInfo->querySeq);
              consumed = 0;
              taos_unsubscribe(tsub,
                      g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
              tsub = subscribeImpl(
6824 6825 6826 6827 6828 6829
                      SPECIFIED_CLASS,
                      pThreadInfo,
                      g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
                      topic,
                      g_queryInfo.specifiedQueryInfo.subscribeRestart,
                      g_queryInfo.specifiedQueryInfo.subscribeInterval);
6830
              if (NULL == tsub) {
6831 6832
                taos_close(pThreadInfo->taos);
                return NULL;
6833 6834
              }
          }
6835 6836 6837
      }
  }
  taos_free_result(res);
6838
  taos_unsubscribe(tsub, 0);
6839
  taos_close(pThreadInfo->taos);
6840

H
hzcheng 已提交
6841 6842 6843
  return NULL;
}

6844
static int subscribeTestProcess() {
6845
  setupForAnsiEscape();
6846
  printfQueryMeta();
6847
  resetAfterAnsiEscape();
6848

6849
  prompt();
6850

6851 6852 6853 6854 6855
  TAOS * taos = NULL;
  taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          g_queryInfo.dbName,
6856
          g_queryInfo.port);
6857
  if (taos == NULL) {
6858 6859
    errorPrint( "Failed to connect to TDengine, reason:%s\n",
            taos_errstr(NULL));
6860 6861 6862
    exit(-1);
  }

6863
  if (0 != g_queryInfo.superQueryInfo.sqlCount) {
6864 6865
    getAllChildNameOfSuperTable(taos,
            g_queryInfo.dbName,
6866 6867 6868
            g_queryInfo.superQueryInfo.sTblName,
            &g_queryInfo.superQueryInfo.childTblName,
            &g_queryInfo.superQueryInfo.childTblCount);
6869 6870
  }

6871 6872
  taos_close(taos); // TODO: workaround to use separate taos connection;

6873 6874
  pthread_t  *pids = NULL;
  threadInfo *infos = NULL;
6875 6876 6877 6878 6879

  pthread_t  *pidsOfStable  = NULL;
  threadInfo *infosOfStable = NULL;

  //==== create threads for query for specified table
6880
  if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) {
6881
    debugPrint("%s() LN%d, sepcified query sqlCount %"PRIu64".\n",
6882
              __func__, __LINE__,
6883 6884 6885 6886 6887 6888 6889 6890
              g_queryInfo.specifiedQueryInfo.sqlCount);
  } else {
    if (g_queryInfo.specifiedQueryInfo.concurrent <= 0) {
        errorPrint("%s() LN%d, sepcified query sqlCount %"PRIu64".\n",
              __func__, __LINE__,
              g_queryInfo.specifiedQueryInfo.sqlCount);
        exit(-1);
    }
6891

6892
    pids  = malloc(
6893 6894 6895
            g_queryInfo.specifiedQueryInfo.sqlCount *
            g_queryInfo.specifiedQueryInfo.concurrent *
            sizeof(pthread_t));
6896
    infos = malloc(
6897 6898 6899
            g_queryInfo.specifiedQueryInfo.sqlCount *
            g_queryInfo.specifiedQueryInfo.concurrent *
            sizeof(threadInfo));
6900 6901 6902 6903
    if ((NULL == pids) || (NULL == infos)) {
        errorPrint("%s() LN%d, malloc failed for create threads\n", __func__, __LINE__);
        exit(-1);
    }
6904

6905 6906 6907 6908 6909 6910 6911 6912 6913
    for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) {
        for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) {
            uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j;
            threadInfo *t_info = infos + seq;
            t_info->threadID = seq;
            t_info->querySeq = i;
            t_info->taos = NULL;  // TODO: workaround to use separate taos connection;
            pthread_create(pids + seq, NULL, specifiedSubscribe, t_info);
        }
6914
    }
H
hzcheng 已提交
6915
  }
6916

6917
  //==== create threads for super table query
6918 6919
  if (g_queryInfo.superQueryInfo.sqlCount <= 0) {
    printf("%s() LN%d, super table query sqlCount %"PRIu64".\n",
6920
              __func__, __LINE__,
6921
              g_queryInfo.superQueryInfo.sqlCount);
6922 6923
  } else {
    if ((g_queryInfo.superQueryInfo.sqlCount > 0)
6924
          && (g_queryInfo.superQueryInfo.threadCnt > 0)) {
6925 6926 6927
        pidsOfStable  = malloc(
                g_queryInfo.superQueryInfo.sqlCount *
                g_queryInfo.superQueryInfo.threadCnt *
6928
            sizeof(pthread_t));
6929 6930 6931
        infosOfStable = malloc(
                g_queryInfo.superQueryInfo.sqlCount *
                g_queryInfo.superQueryInfo.threadCnt *
6932
            sizeof(threadInfo));
6933 6934
        if ((NULL == pidsOfStable) || (NULL == infosOfStable)) {
            errorPrint("%s() LN%d, malloc failed for create threads\n",
6935
              __func__, __LINE__);
6936 6937 6938
            // taos_close(taos);
            exit(-1);
        }
6939

6940 6941
        int64_t ntables = g_queryInfo.superQueryInfo.childTblCount;
        int threads = g_queryInfo.superQueryInfo.threadCnt;
6942

6943 6944 6945 6946 6947
        int64_t a = ntables / threads;
        if (a < 1) {
            threads = ntables;
            a = 1;
        }
6948

6949 6950 6951 6952
        int64_t b = 0;
        if (threads != 0) {
            b = ntables % threads;
        }
6953

6954
        for (uint64_t i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) {
6955
            uint64_t startFrom = 0;
6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970
            for (int j = 0; j < threads; j++) {
                uint64_t seq = i * threads + j;
                threadInfo *t_info = infosOfStable + seq;
                t_info->threadID = seq;
                t_info->querySeq = i;

                t_info->start_table_from = startFrom;
                t_info->ntables = j<b?a+1:a;
                t_info->end_table_to = j<b?startFrom+a:startFrom+a-1;
                startFrom = t_info->end_table_to + 1;
                t_info->taos = NULL; // TODO: workaround to use separate taos connection;
                pthread_create(pidsOfStable + seq,
                        NULL, superSubscribe, t_info);
            }
        }
6971

6972
        g_queryInfo.superQueryInfo.threadCnt = threads;
6973

6974 6975 6976 6977 6978 6979
        for (int i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) {
            for (int j = 0; j < threads; j++) {
                uint64_t seq = i * threads + j;
                pthread_join(pidsOfStable[seq], NULL);
            }
        }
6980
    }
H
hzcheng 已提交
6981
  }
6982

6983 6984 6985 6986 6987
  for (int i = 0; i < g_queryInfo.specifiedQueryInfo.sqlCount; i++) {
    for (int j = 0; j < g_queryInfo.specifiedQueryInfo.concurrent; j++) {
        uint64_t seq = i * g_queryInfo.specifiedQueryInfo.concurrent + j;
        pthread_join(pids[seq], NULL);
    }
6988
  }
H
hzcheng 已提交
6989

6990
  tmfree((char*)pids);
6991
  tmfree((char*)infos);
H
hzcheng 已提交
6992

6993 6994
  tmfree((char*)pidsOfStable);
  tmfree((char*)infosOfStable);
6995
//   taos_close(taos);
6996
  return 0;
H
hzcheng 已提交
6997 6998
}

6999
static void initOfInsertMeta() {
7000
  memset(&g_Dbs, 0, sizeof(SDbs));
7001

7002
  // set default values
7003
  tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
7004
  g_Dbs.port = 6030;
7005 7006
  tstrncpy(g_Dbs.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE);
  tstrncpy(g_Dbs.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE);
7007
  g_Dbs.threadCount = 2;
7008 7009

  g_Dbs.use_metric = g_args.use_metric;
L
Liu Tao 已提交
7010 7011
}

7012
static void initOfQueryMeta() {
7013
  memset(&g_queryInfo, 0, sizeof(SQueryMetaInfo));
7014

7015
  // set default values
7016
  tstrncpy(g_queryInfo.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
7017
  g_queryInfo.port = 6030;
7018 7019
  tstrncpy(g_queryInfo.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE);
  tstrncpy(g_queryInfo.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE);
L
Liu Tao 已提交
7020 7021
}

7022
static void setParaFromArg(){
7023
  if (g_args.host) {
7024
    tstrncpy(g_Dbs.host, g_args.host, MAX_HOSTNAME_SIZE);
7025
  } else {
7026
    tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
7027
  }
L
Liu Tao 已提交
7028

7029
  if (g_args.user) {
7030
    tstrncpy(g_Dbs.user, g_args.user, MAX_USERNAME_SIZE);
7031
  }
7032 7033

  if (g_args.password) {
7034
    tstrncpy(g_Dbs.password, g_args.password, MAX_PASSWORD_SIZE);
7035 7036
  }

7037 7038
  if (g_args.port) {
    g_Dbs.port = g_args.port;
7039
  }
L
Liu Tao 已提交
7040

7041 7042 7043
  g_Dbs.threadCount = g_args.num_of_threads;
  g_Dbs.threadCountByCreateTbl = g_args.num_of_threads;

7044 7045
  g_Dbs.dbCount = 1;
  g_Dbs.db[0].drop = 1;
7046

7047
  tstrncpy(g_Dbs.db[0].dbName, g_args.database, MAX_DB_NAME_SIZE);
7048
  g_Dbs.db[0].dbCfg.replica = g_args.replica;
7049
  tstrncpy(g_Dbs.db[0].dbCfg.precision, "ms", MAX_DB_NAME_SIZE);
L
Liu Tao 已提交
7050

7051
  tstrncpy(g_Dbs.resultFile, g_args.output_file, MAX_FILE_NAME_LEN);
7052 7053 7054 7055 7056

  g_Dbs.use_metric = g_args.use_metric;
  g_Dbs.insert_only = g_args.insert_only;

  g_Dbs.do_aggreFunc = true;
L
Liu Tao 已提交
7057

7058 7059
  char dataString[STRING_LEN];
  char **data_type = g_args.datatype;
7060

7061
  memset(dataString, 0, STRING_LEN);
L
Liu Tao 已提交
7062

7063 7064
  if (strcasecmp(data_type[0], "BINARY") == 0
          || strcasecmp(data_type[0], "BOOL") == 0
7065
          || strcasecmp(data_type[0], "NCHAR") == 0 ) {
7066
    g_Dbs.do_aggreFunc = false;
L
Liu Tao 已提交
7067
  }
H
hzcheng 已提交
7068

7069 7070 7071 7072 7073
  if (g_args.use_metric) {
    g_Dbs.db[0].superTblCount = 1;
    tstrncpy(g_Dbs.db[0].superTbls[0].sTblName, "meters", MAX_TB_NAME_SIZE);
    g_Dbs.db[0].superTbls[0].childTblCount = g_args.num_of_tables;
    g_Dbs.threadCount = g_args.num_of_threads;
7074
    g_Dbs.threadCountByCreateTbl = g_args.num_of_threads;
7075
    g_Dbs.asyncMode = g_args.async_mode;
7076

7077 7078 7079 7080
    g_Dbs.db[0].superTbls[0].autoCreateTable = PRE_CREATE_SUBTBL;
    g_Dbs.db[0].superTbls[0].childTblExists = TBL_NO_EXISTS;
    g_Dbs.db[0].superTbls[0].disorderRange = g_args.disorderRange;
    g_Dbs.db[0].superTbls[0].disorderRatio = g_args.disorderRatio;
7081
    tstrncpy(g_Dbs.db[0].superTbls[0].childTblPrefix,
7082 7083 7084
            g_args.tb_prefix, MAX_TB_NAME_SIZE);
    tstrncpy(g_Dbs.db[0].superTbls[0].dataSource, "rand", MAX_TB_NAME_SIZE);
    tstrncpy(g_Dbs.db[0].superTbls[0].insertMode, "taosc", MAX_TB_NAME_SIZE);
7085
    tstrncpy(g_Dbs.db[0].superTbls[0].startTimestamp,
7086
            "2017-07-14 10:40:00.000", MAX_TB_NAME_SIZE);
7087
    g_Dbs.db[0].superTbls[0].timeStampStep = DEFAULT_TIMESTAMP_STEP;
7088

7089
    g_Dbs.db[0].superTbls[0].insertRows = g_args.num_of_DPT;
7090
    g_Dbs.db[0].superTbls[0].maxSqlLen = g_args.max_sql_len;
7091

7092 7093 7094 7095 7096
    g_Dbs.db[0].superTbls[0].columnCount = 0;
    for (int i = 0; i < MAX_NUM_DATATYPE; i++) {
      if (data_type[i] == NULL) {
        break;
      }
7097

7098
      tstrncpy(g_Dbs.db[0].superTbls[0].columns[i].dataType,
7099
              data_type[i], MAX_TB_NAME_SIZE);
7100
      g_Dbs.db[0].superTbls[0].columns[i].dataLen = g_args.len_of_binary;
7101 7102
      g_Dbs.db[0].superTbls[0].columnCount++;
    }
7103

7104 7105 7106
    if (g_Dbs.db[0].superTbls[0].columnCount > g_args.num_of_CPR) {
      g_Dbs.db[0].superTbls[0].columnCount = g_args.num_of_CPR;
    } else {
7107 7108 7109 7110
      for (int i = g_Dbs.db[0].superTbls[0].columnCount;
              i < g_args.num_of_CPR; i++) {
        tstrncpy(g_Dbs.db[0].superTbls[0].columns[i].dataType,
                "INT", MAX_TB_NAME_SIZE);
7111
        g_Dbs.db[0].superTbls[0].columns[i].dataLen = 0;
7112 7113 7114
        g_Dbs.db[0].superTbls[0].columnCount++;
      }
    }
7115

7116 7117
    tstrncpy(g_Dbs.db[0].superTbls[0].tags[0].dataType,
            "INT", MAX_TB_NAME_SIZE);
7118
    g_Dbs.db[0].superTbls[0].tags[0].dataLen = 0;
7119

7120 7121
    tstrncpy(g_Dbs.db[0].superTbls[0].tags[1].dataType,
            "BINARY", MAX_TB_NAME_SIZE);
7122 7123
    g_Dbs.db[0].superTbls[0].tags[1].dataLen = g_args.len_of_binary;
    g_Dbs.db[0].superTbls[0].tagCount = 2;
7124
  } else {
7125 7126
    g_Dbs.threadCountByCreateTbl = g_args.num_of_threads;
    g_Dbs.db[0].superTbls[0].tagCount = 0;
H
hzcheng 已提交
7127
  }
7128 7129 7130 7131 7132 7133
}

/* Function to do regular expression check */
static int regexMatch(const char *s, const char *reg, int cflags) {
  regex_t regex;
  char    msgbuf[100] = {0};
H
hzcheng 已提交
7134

7135 7136 7137
  /* Compile regular expression */
  if (regcomp(&regex, reg, cflags) != 0) {
    printf("Fail to compile regex\n");
H
Hui Li 已提交
7138 7139 7140
    exit(-1);
  }

7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164
  /* Execute regular expression */
  int reti = regexec(&regex, s, 0, NULL, 0);
  if (!reti) {
    regfree(&regex);
    return 1;
  } else if (reti == REG_NOMATCH) {
    regfree(&regex);
    return 0;
  } else {
    regerror(reti, &regex, msgbuf, sizeof(msgbuf));
    printf("Regex match failed: %s\n", msgbuf);
    regfree(&regex);
    exit(-1);
  }

  return 0;
}

static int isCommentLine(char *line) {
  if (line == NULL) return 1;

  return regexMatch(line, "^\\s*#.*", REG_EXTENDED);
}

7165
static void querySqlFile(TAOS* taos, char* sqlFile)
7166 7167 7168 7169 7170 7171
{
  FILE *fp = fopen(sqlFile, "r");
  if (fp == NULL) {
    printf("failed to open file %s, reason:%s\n", sqlFile, strerror(errno));
    return;
  }
7172

7173 7174 7175 7176 7177 7178
  int       read_len = 0;
  char *    cmd = calloc(1, MAX_SQL_SIZE);
  size_t    cmd_len = 0;
  char *    line = NULL;
  size_t    line_len = 0;

7179
  double t = taosGetTimestampMs();
7180

7181
  while((read_len = tgetline(&line, &line_len, fp)) != -1) {
7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193
    if (read_len >= MAX_SQL_SIZE) continue;
    line[--read_len] = '\0';

    if (read_len == 0 || isCommentLine(line)) {  // line starts with #
      continue;
    }

    if (line[read_len - 1] == '\\') {
      line[read_len - 1] = ' ';
      memcpy(cmd + cmd_len, line, read_len);
      cmd_len += read_len;
      continue;
7194
    }
7195 7196

    memcpy(cmd + cmd_len, line, read_len);
7197
    verbosePrint("%s() LN%d cmd: %s\n", __func__, __LINE__, cmd);
7198 7199 7200
    if (0 != queryDbExec(taos, cmd, NO_INSERT_TYPE, false)) {
        errorPrint("%s() LN%d, queryDbExec %s failed!\n",
               __func__, __LINE__, cmd);
7201 7202 7203 7204 7205
        tmfree(cmd);
        tmfree(line);
        tmfclose(fp);
        return;
    }
7206 7207
    memset(cmd, 0, MAX_SQL_SIZE);
    cmd_len = 0;
H
hzcheng 已提交
7208 7209
  }

7210
  t = taosGetTimestampMs() - t;
7211
  printf("run %s took %.6f second(s)\n\n", sqlFile, t);
7212

7213 7214 7215 7216
  tmfree(cmd);
  tmfree(line);
  tmfclose(fp);
  return;
H
hzcheng 已提交
7217 7218
}

7219
static void testMetaFile() {
7220
    if (INSERT_TEST == g_args.test_mode) {
7221 7222
      if (g_Dbs.cfgDir[0])
          taos_options(TSDB_OPTION_CONFIGDIR, g_Dbs.cfgDir);
7223

7224
      insertTestProcess();
7225

7226
    } else if (QUERY_TEST == g_args.test_mode) {
7227 7228
      if (g_queryInfo.cfgDir[0])
          taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir);
7229

7230
      queryTestProcess();
7231

7232
    } else if (SUBSCRIBE_TEST == g_args.test_mode) {
7233 7234
      if (g_queryInfo.cfgDir[0])
          taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir);
7235

7236
      subscribeTestProcess();
7237

7238 7239 7240
    }  else {
      ;
    }
7241
}
7242

7243
static void queryResult() {
7244
  // query data
7245

7246 7247 7248 7249 7250
  pthread_t read_id;
  threadInfo *rInfo = malloc(sizeof(threadInfo));
  assert(rInfo);
  rInfo->start_time = 1500000000000;  // 2017-07-14 10:40:00.000
  rInfo->start_table_from = 0;
7251

7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287
  //rInfo->do_aggreFunc = g_Dbs.do_aggreFunc;
  if (g_args.use_metric) {
    rInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount;
    rInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1;
    rInfo->superTblInfo = &g_Dbs.db[0].superTbls[0];
    tstrncpy(rInfo->tb_prefix,
          g_Dbs.db[0].superTbls[0].childTblPrefix, MAX_TB_NAME_SIZE);
  } else {
    rInfo->ntables = g_args.num_of_tables;
    rInfo->end_table_to = g_args.num_of_tables -1;
    tstrncpy(rInfo->tb_prefix, g_args.tb_prefix, MAX_TB_NAME_SIZE);
  }

  rInfo->taos = taos_connect(
          g_Dbs.host,
          g_Dbs.user,
          g_Dbs.password,
          g_Dbs.db[0].dbName,
          g_Dbs.port);
  if (rInfo->taos == NULL) {
    errorPrint( "Failed to connect to TDengine, reason:%s\n",
            taos_errstr(NULL));
    free(rInfo);
    exit(-1);
  }

  tstrncpy(rInfo->fp, g_Dbs.resultFile, MAX_FILE_NAME_LEN);

  if (!g_Dbs.use_metric) {
    pthread_create(&read_id, NULL, readTable, rInfo);
  } else {
    pthread_create(&read_id, NULL, readMetric, rInfo);
  }
  pthread_join(read_id, NULL);
  taos_close(rInfo->taos);
  free(rInfo);
7288 7289
}

7290 7291
static void testCmdLine() {

7292 7293 7294 7295 7296 7297 7298 7299 7300 7301
  if (strlen(configDir)) {
    wordexp_t full_path;
    if (wordexp(configDir, &full_path, 0) != 0) {
      errorPrint( "Invalid path %s\n", configDir);
      return;
    }
    taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]);
    wordfree(&full_path);
  }

7302 7303
  g_args.test_mode = INSERT_TEST;
  insertTestProcess();
7304

7305
  if (false == g_Dbs.insert_only)
7306
    queryResult();
7307 7308
}

7309 7310 7311
int main(int argc, char *argv[]) {
  parse_args(argc, argv, &g_args);

7312
  debugPrint("meta file: %s\n", g_args.metaFile);
7313 7314 7315

  if (g_args.metaFile) {
    initOfInsertMeta();
7316
    initOfQueryMeta();
7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329

    if (false == getInfoFromJsonFile(g_args.metaFile)) {
      printf("Failed to read %s\n", g_args.metaFile);
      return 1;
    }

    testMetaFile();
  } else {
    memset(&g_Dbs, 0, sizeof(SDbs));
    setParaFromArg();

    if (NULL != g_args.sqlFile) {
      TAOS* qtaos = taos_connect(
7330 7331 7332 7333
          g_Dbs.host,
          g_Dbs.user,
          g_Dbs.password,
          g_Dbs.db[0].dbName,
7334
          g_Dbs.port);
7335
      querySqlFile(qtaos, g_args.sqlFile);
7336 7337 7338 7339 7340
      taos_close(qtaos);

    } else {
      testCmdLine();
    }
7341 7342 7343

    if (g_dupstr)
        free(g_dupstr);
H
hzcheng 已提交
7344
  }
7345 7346

  return 0;
H
hzcheng 已提交
7347
}
7348