taosdemo.c 257.8 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>
22
#include <taos.h>
S
slguan 已提交
23
#define _GNU_SOURCE
24 25
#define CURL_STATICLIB

S
TD-1057  
Shengliang Guan 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
#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>
42
#else
S
TD-1057  
Shengliang Guan 已提交
43 44
  #include <regex.h>
  #include <stdio.h>
45
#endif
H
hzcheng 已提交
46

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

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

56 57 58
#define REQ_EXTRA_BUF_LEN   1024
#define RESP_BUF_LEN        4096

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

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

65 66
#define STR_INSERT_INTO     "INSERT INTO "

67 68 69 70 71 72
enum TEST_MODE {
    INSERT_TEST,            // 0
    QUERY_TEST,             // 1
    SUBSCRIBE_TEST,         // 2
    INVAID_TEST
};
73

74 75
#define MAX_RECORDS_PER_REQ     32766

76 77
#define HEAD_BUFF_LEN    1024*24  // 16*1024 + (192+32)*2 + insert into ..

78 79
#define MAX_SQL_SIZE       65536
#define BUFFER_SIZE        (65536*2)
80
#define COND_BUF_LEN        BUFFER_SIZE - 30
81 82
#define MAX_USERNAME_SIZE  64
#define MAX_PASSWORD_SIZE  64
83
#define MAX_DB_NAME_SIZE   64
84
#define MAX_HOSTNAME_SIZE  64
85
#define MAX_TB_NAME_SIZE   64
86
#define MAX_DATA_SIZE      (16*1024)+20     // max record len: 16*1024, timestamp string and ,('') need extra space
87 88 89 90 91 92 93 94 95 96
#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
97
#define   MAX_SUPER_TABLE_COUNT  200
98 99 100
#define   MAX_COLUMN_COUNT       1024
#define   MAX_TAG_COUNT          128

101
#define   MAX_QUERY_SQL_COUNT    100
102
#define   MAX_QUERY_SQL_LENGTH   1024
103 104

#define   MAX_DATABASE_COUNT     256
105
#define INPUT_BUF_LEN   256
106

107
#define DEFAULT_TIMESTAMP_STEP  1
108

109

110 111 112 113 114
typedef enum CREATE_SUB_TALBE_MOD_EN {
  PRE_CREATE_SUBTBL,
  AUTO_CREATE_SUBTBL,
  NO_CREATE_SUBTBL
} CREATE_SUB_TALBE_MOD_EN;
115

116 117
typedef enum TALBE_EXISTS_EN {
  TBL_NO_EXISTS,
118
  TBL_ALREADY_EXISTS,
119 120 121
  TBL_EXISTS_BUTT
} TALBE_EXISTS_EN;

122
enum enumSYNC_MODE {
123 124
  SYNC_MODE,
  ASYNC_MODE,
125 126
  MODE_BUT
};
127

S
Shuduo Sang 已提交
128
enum enum_TAOS_INTERFACE {
129 130 131
    TAOSC_IFACE,
    REST_IFACE,
    STMT_IFACE,
132 133 134
    INTERFACE_BUT
};

135 136 137 138 139 140
typedef enum enumQUERY_CLASS {
    SPECIFIED_CLASS,
    STABLE_CLASS,
    CLASS_BUT
} QUERY_CLASS;

S
Shuduo Sang 已提交
141
typedef enum enum_PROGRESSIVE_OR_INTERLACE {
142 143 144
    PROGRESSIVE_INSERT_MODE,
    INTERLACE_INSERT_MODE,
    INVALID_INSERT_MODE
145
} PROG_OR_INTERLACE_MODE;
146

147
typedef enum enumQUERY_TYPE {
148
  NO_INSERT_TYPE,
149
  INSERT_TYPE,
150
  QUERY_TYPE_BUT
151
} QUERY_TYPE;
152 153 154 155 156 157 158

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,
159
  TSDB_SHOW_DB_QUORUM_INDEX,
160 161 162 163 164 165 166 167 168 169
  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,
170
  TSDB_SHOW_DB_PRECISION_INDEX,
171 172 173 174 175 176 177 178 179 180
  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,
181 182
  TSDB_SHOW_STABLES_METRIC_INDEX,
  TSDB_SHOW_STABLES_UID_INDEX,
183
  TSDB_SHOW_STABLES_TID_INDEX,
184
  TSDB_SHOW_STABLES_VGID_INDEX,
185
  TSDB_MAX_SHOW_STABLES
186 187
};

188 189 190 191 192 193 194 195 196 197 198 199 200 201
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 已提交
202 203

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

206 207
typedef struct SArguments_S {
  char *   metaFile;
208
  uint32_t test_mode;
209 210
  char *   host;
  uint16_t port;
S
Shuduo Sang 已提交
211
  uint16_t iface;
212 213 214 215 216 217 218
  char *   user;
  char *   password;
  char *   database;
  int      replica;
  char *   tb_prefix;
  char *   sqlFile;
  bool     use_metric;
219
  bool     drop_database;
220
  bool     insert_only;
221
  bool     answer_yes;
222
  bool     debug_print;
223
  bool     verbose_print;
224
  bool     performance_print;
225
  char *   output_file;
226
  bool     async_mode;
227
  char *   datatype[MAX_NUM_DATATYPE + 1];
228 229 230 231
  uint32_t len_of_binary;
  uint32_t num_of_CPR;
  uint32_t num_of_threads;
  uint64_t insert_interval;
232
  int64_t  query_times;
233 234
  uint32_t interlace_rows;
  uint32_t num_of_RPR;                  // num_of_records_per_req
235
  uint64_t max_sql_len;
236 237
  int64_t  num_of_tables;
  int64_t  num_of_DPT;
238
  int      abort;
239
  uint32_t disorderRatio;               // 0: no disorder, >0: x%
240
  int      disorderRange;               // ms or us by database precision
241
  uint32_t method_of_delete;
242
  char **  arg_list;
243 244
  uint64_t totalInsertRows;
  uint64_t totalAffectedRows;
245 246 247
} SArguments;

typedef struct SColumn_S {
248 249 250
  char      field[TSDB_COL_NAME_LEN + 1];
  char      dataType[MAX_TB_NAME_SIZE];
  uint32_t  dataLen;
251
  char      note[128];
252 253 254
} StrColumn;

typedef struct SSuperTable_S {
255
  char         sTblName[MAX_TB_NAME_SIZE+1];
256
  int64_t      childTblCount;
257
  bool         childTblExists;          // 0: no, 1: yes
258 259
  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
260
  char         childTblPrefix[MAX_TB_NAME_SIZE];
261
  char         dataSource[MAX_TB_NAME_SIZE+1];  // rand_gen or sample
262
  uint16_t     iface;                   // 0: taosc, 1: rest, 2: stmt
263
  int64_t      childTblLimit;
264
  uint64_t     childTblOffset;
265

266
//  int          multiThreadWriteOneTbl;  // 0: no, 1: yes
267
  uint32_t     interlaceRows;           //
268 269
  int          disorderRatio;           // 0: no disorder, >0: x%
  int          disorderRange;           // ms or us by database precision
270
  uint64_t     maxSqlLen;               //
271

272
  uint64_t     insertInterval;          // insert interval, will override global insert interval
273
  int64_t      insertRows;
274
  int64_t      timeStampStep;
275
  char         startTimestamp[MAX_TB_NAME_SIZE];
276
  char         sampleFormat[MAX_TB_NAME_SIZE];  // csv, json
277 278
  char         sampleFile[MAX_FILE_NAME_LEN+1];
  char         tagsFile[MAX_FILE_NAME_LEN+1];
279

280
  uint32_t     columnCount;
281
  StrColumn    columns[MAX_COLUMN_COUNT];
282
  uint32_t     tagCount;
283 284 285
  StrColumn    tags[MAX_TAG_COUNT];

  char*        childTblName;
286
  char*        colsOfCreateChildTable;
287 288
  uint64_t     lenOfOneRow;
  uint64_t     lenOfTagOfOneRow;
289 290 291 292 293

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

294
  uint32_t     tagSource;    // 0: rand, 1: tag sample
295
  char*        tagDataBuf;
296 297
  uint32_t     tagSampleCount;
  uint32_t     tagUsePos;
298

299
  // statistics
300 301
  uint64_t     totalInsertRows;
  uint64_t     totalAffectedRows;
302 303 304 305 306
} SSuperTable;

typedef struct {
  char     name[TSDB_DB_NAME_LEN + 1];
  char     create_time[32];
S
Shuduo Sang 已提交
307
  int64_t  ntables;
308
  int32_t  vgroups;
309 310
  int16_t  replica;
  int16_t  quorum;
311
  int16_t  days;
312 313 314 315 316 317 318 319 320 321 322 323 324 325
  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;

326
typedef struct SDbCfg_S {
327
//  int       maxtablesPerVnode;
328 329
  uint32_t  minRows;        // 0 means default
  uint32_t  maxRows;        // 0 means default
330 331
  int       comp;
  int       walLevel;
332
  int       cacheLast;
333
  int       fsync;
334 335 336 337 338 339 340
  int       replica;
  int       update;
  int       keep;
  int       days;
  int       cache;
  int       blocks;
  int       quorum;
341
  char      precision[MAX_TB_NAME_SIZE];
342 343 344 345
} SDbCfg;

typedef struct SDataBase_S {
  char         dbName[MAX_DB_NAME_SIZE];
346
  bool         drop;  // 0: use exists, 1: if exists, drop then new create
347
  SDbCfg       dbCfg;
348
  uint64_t     superTblCount;
349 350 351 352
  SSuperTable  superTbls[MAX_SUPER_TABLE_COUNT];
} SDataBase;

typedef struct SDbs_S {
353
  char         cfgDir[MAX_FILE_NAME_LEN+1];
354
  char         host[MAX_HOSTNAME_SIZE];
355 356
  struct sockaddr_in serv_addr;

357
  uint16_t     port;
358 359
  char         user[MAX_USERNAME_SIZE];
  char         password[MAX_PASSWORD_SIZE];
360
  char         resultFile[MAX_FILE_NAME_LEN+1];
361 362 363
  bool         use_metric;
  bool         insert_only;
  bool         do_aggreFunc;
364
  bool         asyncMode;
365

366 367 368
  uint32_t     threadCount;
  uint32_t     threadCountByCreateTbl;
  uint32_t     dbCount;
369 370 371
  SDataBase    db[MAX_DB_COUNT];

  // statistics
372 373
  uint64_t     totalInsertRows;
  uint64_t     totalAffectedRows;
374

375 376
} SDbs;

377
typedef struct SpecifiedQueryInfo_S {
378
  uint64_t     queryInterval;  // 0: unlimit  > 0   loop/s
379
  uint32_t     concurrent;
380
  uint64_t     sqlCount;
381
  uint32_t     asyncMode; // 0: sync, 1: async
382 383
  uint64_t     subscribeInterval; // ms
  uint64_t     queryTimes;
384
  bool         subscribeRestart;
385
  int          subscribeKeepProgress;
386
  char         sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1];
387
  char         result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1];
388
  int          resubAfterConsume[MAX_QUERY_SQL_COUNT];
389
  TAOS_SUB*    tsub[MAX_QUERY_SQL_COUNT];
390 391 392
  char         topic[MAX_QUERY_SQL_COUNT][32];
  int          consumed[MAX_QUERY_SQL_COUNT];
  TAOS_RES*    res[MAX_QUERY_SQL_COUNT];
393
  uint64_t     totalQueried;
394
} SpecifiedQueryInfo;
395

396
typedef struct SuperQueryInfo_S {
397
  char         sTblName[MAX_TB_NAME_SIZE+1];
398 399
  uint64_t     queryInterval;  // 0: unlimit  > 0   loop/s
  uint32_t     threadCnt;
400
  uint32_t     asyncMode; // 0: sync, 1: async
401
  uint64_t     subscribeInterval; // ms
402
  bool         subscribeRestart;
403
  int          subscribeKeepProgress;
404
  uint64_t     queryTimes;
405
  int64_t      childTblCount;
406
  char         childTblPrefix[MAX_TB_NAME_SIZE];
407
  uint64_t     sqlCount;
408
  char         sql[MAX_QUERY_SQL_COUNT][MAX_QUERY_SQL_LENGTH+1];
409
  char         result[MAX_QUERY_SQL_COUNT][MAX_FILE_NAME_LEN+1];
410
  int          resubAfterConsume;
411
  TAOS_SUB*    tsub[MAX_QUERY_SQL_COUNT];
412

413
  char*        childTblName;
414
  uint64_t     totalQueried;
415
} SuperQueryInfo;
416 417

typedef struct SQueryMetaInfo_S {
418
  char         cfgDir[MAX_FILE_NAME_LEN+1];
419
  char         host[MAX_HOSTNAME_SIZE];
420
  uint16_t     port;
421
  struct       sockaddr_in serv_addr;
422 423
  char         user[MAX_USERNAME_SIZE];
  char         password[MAX_PASSWORD_SIZE];
424
  char         dbName[MAX_DB_NAME_SIZE+1];
425
  char         queryMode[MAX_TB_NAME_SIZE];  // taosc, rest
426

427
  SpecifiedQueryInfo  specifiedQueryInfo;
428
  SuperQueryInfo      superQueryInfo;
429
  uint64_t     totalQueried;
430 431 432
} SQueryMetaInfo;

typedef struct SThreadInfo_S {
433
  TAOS *    taos;
434
  TAOS_STMT *stmt;
435 436 437
  int       threadID;
  char      db_name[MAX_DB_NAME_SIZE+1];
  uint32_t  time_precision;
438 439
  char      filePath[4096];
  FILE      *fp;
440 441 442
  char      tb_prefix[MAX_TB_NAME_SIZE];
  uint64_t  start_table_from;
  uint64_t  end_table_to;
S
Shuduo Sang 已提交
443
  int64_t   ntables;
444 445 446 447
  uint64_t  data_of_rate;
  int64_t   start_time;
  char*     cols;
  bool      use_metric;
448
  SSuperTable* superTblInfo;
S
Shuduo Sang 已提交
449
  char      *buffer;    // sql cmd buffer
450 451

  // for async insert
452 453
  tsem_t    lock_sem;
  int64_t   counter;
454 455
  uint64_t  st;
  uint64_t  et;
456
  uint64_t  lastTs;
457

458
  // sample data
459
  int64_t   samplePos;
460
  // statistics
461 462
  uint64_t  totalInsertRows;
  uint64_t  totalAffectedRows;
463 464

  // insert delay statistics
465 466 467 468 469
  uint64_t  cntDelay;
  uint64_t  totalDelay;
  uint64_t  avgDelay;
  uint64_t  maxDelay;
  uint64_t  minDelay;
470

471
  // seq of query or subscribe
472
  uint64_t  querySeq;   // sequence number of sql command
473
  TAOS_SUB*  tsub;
474

475 476
} threadInfo;

477
#ifdef WINDOWS
478 479
#define _CRT_RAND_S

480
#include <windows.h>
481 482 483 484 485
#include <winsock2.h>

typedef unsigned __int32 uint32_t;

#pragma comment ( lib, "ws2_32.lib" )
486 487
// Some old MinGW/CYGWIN distributions don't define this:
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
488 489
  #define ENABLE_VIRTUAL_TERMINAL_PROCESSING  0x0004
#endif // ENABLE_VIRTUAL_TERMINAL_PROCESSING
490 491 492 493

static HANDLE g_stdoutHandle;
static DWORD g_consoleMode;

494
static void setupForAnsiEscape(void) {
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
  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());
513
  }
514 515
}

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

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

526
static int taosRandom()
527 528 529 530 531 532
{
    int number;
    rand_s(&number);

    return number;
}
533
#else   // Not windows
534
static void setupForAnsiEscape(void) {}
535

536
static void resetAfterAnsiEscape(void) {
537 538 539
  // Reset colors
  printf("\x1b[0m");
}
540

541 542
#include <time.h>

543
static int taosRandom()
544
{
545
  return rand();
546 547
}

548
#endif // ifdef Windows
549

550
static void prompt();
551
static int createDatabasesAndStables();
552
static void createChildTables();
553
static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet);
554
static int postProceSql(char *host, struct sockaddr_in *pServAddr,
555
        uint16_t port, char* sqlstr, threadInfo *pThreadInfo);
556 557
static int64_t getTSRandTail(int64_t timeStampStep, int32_t seq,
        int disorderRatio, int disorderRange);
558 559 560 561 562 563 564

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

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

568
SArguments g_args = {
569 570 571 572
                     NULL,            // metaFile
                     0,               // test_mode
                     "127.0.0.1",     // host
                     6030,            // port
S
Shuduo Sang 已提交
573
                     TAOSC_IFACE,     // iface
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
                     "root",          // user
                     #ifdef _TD_POWER_
                     "powerdb",      // password
                     #else
                     "taosdata",      // password
                     #endif
                     "test",          // database
                     1,               // replica
                     "t",             // tb_prefix
                     NULL,            // sqlFile
                     true,            // use_metric
                     true,            // drop_database
                     true,            // insert_only
                     false,           // debug_print
                     false,           // verbose_print
                     false,           // performance statistic print
                     false,           // answer_yes;
                     "./output.txt",  // output_file
                     0,               // mode : sync or async
                     {
                     "INT",           // datatype
                     "INT",           // datatype
                     "INT",           // datatype
                     "INT",           // datatype
                     },
                     16,              // len_of_binary
                     4,               // num_of_CPR
                     10,              // num_of_connections/thread
                     0,               // insert_interval
                     1,               // query_times
                     0,               // interlace_rows;
                     30000,           // num_of_RPR
sangshuduo's avatar
sangshuduo 已提交
606
                     (1024*1024),         // max_sql_len
607 608 609 610 611 612 613
                     10000,           // num_of_tables
                     10000,           // num_of_DPT
                     0,               // abort
                     0,               // disorderRatio
                     1000,            // disorderRange
                     1,               // method_of_delete
                     NULL             // arg_list
614 615 616 617 618
};



static SDbs            g_Dbs;
619
static int64_t         g_totalChildTables = 0;
620 621 622 623
static SQueryMetaInfo  g_queryInfo;
static FILE *          g_fpOfInsertResult = NULL;

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

627
#define verbosePrint(fmt, ...) \
628 629
    do { if (g_args.verbose_print) \
        fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0)
630

631 632 633 634
#define performancePrint(fmt, ...) \
    do { if (g_args.performance_print) \
        fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0)

635 636 637 638
#define errorPrint(fmt, ...) \
    do { fprintf(stderr, "ERROR: "fmt, __VA_ARGS__); } while(0)


639
///////////////////////////////////////////////////
H
hzcheng 已提交
640

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

643 644 645 646 647 648 649 650
#ifndef TAOSDEMO_COMMIT_SHA1
#define TAOSDEMO_COMMIT_SHA1 "unknown"
#endif

#ifndef TD_VERNUMBER
#define TD_VERNUMBER    "unknown"
#endif

651
#ifndef TAOSDEMO_STATUS
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
#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);
    }
}

669
static void printHelp() {
670
  char indent[10] = "        ";
671
  printf("%s%s%s%s\n", indent, "-f", indent,
672
          "The meta file to the execution procedure. Default is './meta.json'.");
673
  printf("%s%s%s%s\n", indent, "-u", indent,
674 675
          "The TDengine user name to use when connecting to the server. Default is 'root'.");
#ifdef _TD_POWER_
676
  printf("%s%s%s%s\n", indent, "-P", indent,
677
          "The password to use when connecting to the server. Default is 'powerdb'.");
678
  printf("%s%s%s%s\n", indent, "-c", indent,
679 680
          "Configuration directory. Default is '/etc/power/'.");
#else
681
  printf("%s%s%s%s\n", indent, "-P", indent,
682
          "The password to use when connecting to the server. Default is 'taosdata'.");
683
  printf("%s%s%s%s\n", indent, "-c", indent,
684
          "Configuration directory. Default is '/etc/taos/'.");
685
#endif
686
  printf("%s%s%s%s\n", indent, "-h", indent,
687
          "The host to connect to TDengine. Default is localhost.");
688
  printf("%s%s%s%s\n", indent, "-p", indent,
689
          "The TCP/IP port number to use for the connection. Default is 0.");
690 691
  printf("%s%s%s%s\n", indent, "-I", indent,
          "The interface (taosc, rest, and stmt) taosdemo uses. Default is 'taosc'.");
692
  printf("%s%s%s%s\n", indent, "-d", indent,
693
          "Destination database. Default is 'test'.");
694
  printf("%s%s%s%s\n", indent, "-a", indent,
695
          "Set the replica parameters of the database, Default 1, min: 1, max: 3.");
696
  printf("%s%s%s%s\n", indent, "-m", indent,
697 698
          "Table prefix name. Default is 't'.");
  printf("%s%s%s%s\n", indent, "-s", indent, "The select sql file.");
699
  printf("%s%s%s%s\n", indent, "-N", indent, "Use normal table flag.");
700
  printf("%s%s%s%s\n", indent, "-o", indent,
701
          "Direct output to the named file. Default is './output.txt'.");
702
  printf("%s%s%s%s\n", indent, "-q", indent,
703
          "Query mode -- 0: SYNC, 1: ASYNC. Default is SYNC.");
704
  printf("%s%s%s%s\n", indent, "-b", indent,
sangshuduo's avatar
sangshuduo 已提交
705
          "The data_type of columns, default: INT,INT,INT,INT.");
706
  printf("%s%s%s%s\n", indent, "-w", indent,
707
          "The length of data_type 'BINARY' or 'NCHAR'. Default is 16");
708 709 710
  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);
711
  printf("%s%s%s%s\n", indent, "-T", indent,
712
          "The number of threads. Default is 10.");
713
  printf("%s%s%s%s\n", indent, "-i", indent,
714
          "The sleep time (ms) between insertion. Default is 0.");
715
  printf("%s%s%s%s\n", indent, "-r", indent,
716
          "The number of records per request. Default is 30000.");
717
  printf("%s%s%s%s\n", indent, "-t", indent,
718
          "The number of tables. Default is 10000.");
719
  printf("%s%s%s%s\n", indent, "-n", indent,
720 721 722
          "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.");
723
  printf("%s%s%s%s\n", indent, "-O", indent,
724
          "Insert mode--0: In order, 1 ~ 50: disorder ratio. Default is in order.");
725
  printf("%s%s%s%s\n", indent, "-R", indent,
726
          "Out of order data's range, ms, default is 1000.");
727
  printf("%s%s%s%s\n", indent, "-g", indent,
728
          "Print debug info.");
729
  printf("%s%s%s\n", indent, "-V, --version\t",
730
          "Print version info.");
731 732
  printf("%s%s%s%s\n", indent, "--help\t", indent,
          "Print command line arguments list info.");
733
/*    printf("%s%s%s%s\n", indent, "-D", indent,
734 735 736 737
          "if elete database if exists. 0: no, 1: yes, default is 1");
          */
}

738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
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;
}

753
static void parse_args(int argc, char *argv[], SArguments *arguments) {
754 755 756 757 758

  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "-f") == 0) {
      arguments->metaFile = argv[++i];
    } else if (strcmp(argv[i], "-c") == 0) {
H
Haojun Liao 已提交
759 760 761 762 763
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-c need a valid path following!\n");
        exit(EXIT_FAILURE);
      }
764
      tstrncpy(configDir, argv[++i], TSDB_FILENAME_LEN);
765
    } else if (strcmp(argv[i], "-h") == 0) {
H
Haojun Liao 已提交
766 767 768 769 770
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-h need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
771 772
      arguments->host = argv[++i];
    } else if (strcmp(argv[i], "-p") == 0) {
773
      if ((argc == i+1) ||
774
        (!isStringNumber(argv[i+1]))) {
775 776 777 778
        printHelp();
        errorPrint("%s", "\n\t-p need a number following!\n");
        exit(EXIT_FAILURE);
      }
779
      arguments->port = atoi(argv[++i]);
780 781 782 783 784 785 786 787
    } else if (strcmp(argv[i], "-I") == 0) {
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-I need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
      ++i;
      if (0 == strcasecmp(argv[i], "taosc")) {
S
Shuduo Sang 已提交
788
          arguments->iface = TAOSC_IFACE;
789
      } else if (0 == strcasecmp(argv[i], "rest")) {
S
Shuduo Sang 已提交
790
          arguments->iface = REST_IFACE;
791
      } else if (0 == strcasecmp(argv[i], "stmt")) {
S
Shuduo Sang 已提交
792
          arguments->iface = STMT_IFACE;
793 794 795 796
      } else {
        errorPrint("%s", "\n\t-I need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
797
    } else if (strcmp(argv[i], "-u") == 0) {
H
Haojun Liao 已提交
798 799 800 801 802
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-u need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
803 804
      arguments->user = argv[++i];
    } else if (strcmp(argv[i], "-P") == 0) {
H
Haojun Liao 已提交
805 806 807 808 809
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-P need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
810 811
      arguments->password = argv[++i];
    } else if (strcmp(argv[i], "-o") == 0) {
H
Haojun Liao 已提交
812 813 814 815 816
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-o need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
817 818
      arguments->output_file = argv[++i];
    } else if (strcmp(argv[i], "-s") == 0) {
H
Haojun Liao 已提交
819 820 821 822 823
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-s need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
824 825
      arguments->sqlFile = argv[++i];
    } else if (strcmp(argv[i], "-q") == 0) {
826 827
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
828
        printHelp();
829
        errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, 1: ASYNC. Default is SYNC.\n");
830 831
        exit(EXIT_FAILURE);
      }
832
      arguments->async_mode = atoi(argv[++i]);
833
    } else if (strcmp(argv[i], "-T") == 0) {
834 835
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
836 837 838 839
        printHelp();
        errorPrint("%s", "\n\t-T need a number following!\n");
        exit(EXIT_FAILURE);
      }
840 841
      arguments->num_of_threads = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-i") == 0) {
842 843
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
844 845 846 847
        printHelp();
        errorPrint("%s", "\n\t-i need a number following!\n");
        exit(EXIT_FAILURE);
      }
848
      arguments->insert_interval = atoi(argv[++i]);
849
    } else if (strcmp(argv[i], "-qt") == 0) {
850
      if ((argc == i+1)
851
              || (!isStringNumber(argv[i+1]))) {
H
Haojun Liao 已提交
852
        printHelp();
853
        errorPrint("%s", "\n\t-qt need a number following!\n");
H
Haojun Liao 已提交
854 855
        exit(EXIT_FAILURE);
      }
856
      arguments->query_times = atoi(argv[++i]);
857
    } else if (strcmp(argv[i], "-B") == 0) {
858 859
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
H
Haojun Liao 已提交
860 861 862 863
        printHelp();
        errorPrint("%s", "\n\t-B need a number following!\n");
        exit(EXIT_FAILURE);
      }
864
      arguments->interlace_rows = atoi(argv[++i]);
865
    } else if (strcmp(argv[i], "-r") == 0) {
866 867
      if ((argc == i+1)
              || (!isStringNumber(argv[i+1]))) {
868 869 870 871
        printHelp();
        errorPrint("%s", "\n\t-r need a number following!\n");
        exit(EXIT_FAILURE);
      }
872 873
      arguments->num_of_RPR = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-t") == 0) {
874 875 876 877 878 879
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-t need a number following!\n");
        exit(EXIT_FAILURE);
      }
880 881
      arguments->num_of_tables = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-n") == 0) {
882 883 884 885 886 887
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-n need a number following!\n");
        exit(EXIT_FAILURE);
      }
888 889
      arguments->num_of_DPT = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-d") == 0) {
H
Haojun Liao 已提交
890 891 892 893 894
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-d need a valid string following!\n");
        exit(EXIT_FAILURE);
      }
895 896
      arguments->database = argv[++i];
    } else if (strcmp(argv[i], "-l") == 0) {
897 898 899 900 901 902
      if (argc == i+1) {
        if (!isStringNumber(argv[i+1])) {
            printHelp();
            errorPrint("%s", "\n\t-l need a number following!\n");
            exit(EXIT_FAILURE);
        }
903
      }
904
      arguments->num_of_CPR = atoi(argv[++i]);
905 906 907 908 909 910 911 912 913 914 915

      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;
      }

916
    } else if (strcmp(argv[i], "-b") == 0) {
917 918 919 920 921
      if (argc == i+1) {
        printHelp();
        errorPrint("%s", "\n\t-b need valid string following!\n");
        exit(EXIT_FAILURE);
      }
922 923
      ++i;
      if (strstr(argv[i], ",") == NULL) {
924
        // only one col
925
        if (strcasecmp(argv[i], "INT")
926 927 928 929 930 931 932
                && strcasecmp(argv[i], "FLOAT")
                && strcasecmp(argv[i], "TINYINT")
                && strcasecmp(argv[i], "BOOL")
                && strcasecmp(argv[i], "SMALLINT")
                && strcasecmp(argv[i], "BIGINT")
                && strcasecmp(argv[i], "DOUBLE")
                && strcasecmp(argv[i], "BINARY")
933
                && strcasecmp(argv[i], "TIMESTAMP")
934
                && strcasecmp(argv[i], "NCHAR")) {
935
          printHelp();
936
          errorPrint("%s", "-b: Invalid data_type!\n");
937
          exit(EXIT_FAILURE);
938
        }
939
        arguments->datatype[0] = argv[i];
940
      } else {
941
        // more than one col
942
        int index = 0;
943 944
        g_dupstr = strdup(argv[i]);
        char *running = g_dupstr;
945
        char *token = strsep(&running, ",");
946
        while(token != NULL) {
947
          if (strcasecmp(token, "INT")
948 949 950 951 952 953 954
                  && strcasecmp(token, "FLOAT")
                  && strcasecmp(token, "TINYINT")
                  && strcasecmp(token, "BOOL")
                  && strcasecmp(token, "SMALLINT")
                  && strcasecmp(token, "BIGINT")
                  && strcasecmp(token, "DOUBLE")
                  && strcasecmp(token, "BINARY")
955
                  && strcasecmp(token, "TIMESTAMP")
956
                  && strcasecmp(token, "NCHAR")) {
957
            printHelp();
958
            free(g_dupstr);
959
            errorPrint("%s", "-b: Invalid data_type!\n");
960
            exit(EXIT_FAILURE);
H
hzcheng 已提交
961
          }
962
          arguments->datatype[index++] = token;
963 964
          token = strsep(&running, ",");
          if (index >= MAX_NUM_DATATYPE) break;
S
TD-1057  
Shengliang Guan 已提交
965
        }
966
        arguments->datatype[index] = NULL;
967
      }
968
    } else if (strcmp(argv[i], "-w") == 0) {
969
      if ((argc == i+1) ||
970
        (!isStringNumber(argv[i+1]))) {
971 972 973 974
        printHelp();
        errorPrint("%s", "\n\t-w need a number following!\n");
        exit(EXIT_FAILURE);
      }
975 976
      arguments->len_of_binary = atoi(argv[++i]);
    } else if (strcmp(argv[i], "-m") == 0) {
H
Haojun Liao 已提交
977
      if ((argc == i+1) ||
978
        (!isStringNumber(argv[i+1]))) {
H
Haojun Liao 已提交
979 980 981 982
        printHelp();
        errorPrint("%s", "\n\t-m need a number following!\n");
        exit(EXIT_FAILURE);
      }
983
      arguments->tb_prefix = argv[++i];
984 985
    } else if (strcmp(argv[i], "-N") == 0) {
      arguments->use_metric = false;
986
    } else if (strcmp(argv[i], "-x") == 0) {
987
      arguments->insert_only = false;
988
    } else if (strcmp(argv[i], "-y") == 0) {
989
      arguments->answer_yes = true;
990 991
    } else if (strcmp(argv[i], "-g") == 0) {
      arguments->debug_print = true;
992 993
    } else if (strcmp(argv[i], "-gg") == 0) {
      arguments->verbose_print = true;
994 995
    } else if (strcmp(argv[i], "-pp") == 0) {
      arguments->performance_print = true;
996
    } else if (strcmp(argv[i], "-O") == 0) {
997 998 999 1000 1001 1002
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-O need a number following!\n");
        exit(EXIT_FAILURE);
      }
1003

1004
      arguments->disorderRatio = atoi(argv[++i]);
1005

1006
      if (arguments->disorderRatio > 50) {
1007
        arguments->disorderRatio = 50;
1008
      }
1009

1010
      if (arguments->disorderRatio < 0) {
1011
        arguments->disorderRatio = 0;
1012
      }
1013

1014
    } else if (strcmp(argv[i], "-R") == 0) {
1015 1016 1017 1018 1019 1020
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-R need a number following!\n");
        exit(EXIT_FAILURE);
      }
1021

1022
      arguments->disorderRange = atoi(argv[++i]);
1023 1024 1025
      if (arguments->disorderRange < 0)
        arguments->disorderRange = 1000;

1026
    } else if (strcmp(argv[i], "-a") == 0) {
1027 1028 1029 1030 1031 1032
      if ((argc == i+1) ||
        (!isStringNumber(argv[i+1]))) {
        printHelp();
        errorPrint("%s", "\n\t-a need a number following!\n");
        exit(EXIT_FAILURE);
      }
1033 1034 1035
      arguments->replica = atoi(argv[++i]);
      if (arguments->replica > 3 || arguments->replica < 1) {
          arguments->replica = 1;
1036
      }
1037 1038
    } else if (strcmp(argv[i], "-D") == 0) {
      arguments->method_of_delete = atoi(argv[++i]);
1039 1040 1041
      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 已提交
1042
      }
1043 1044 1045 1046
    } else if ((strcmp(argv[i], "--version") == 0) ||
        (strcmp(argv[i], "-V") == 0)){
      printVersion();
      exit(0);
1047 1048 1049 1050 1051
    } else if (strcmp(argv[i], "--help") == 0) {
      printHelp();
      exit(0);
    } else {
      printHelp();
1052
      errorPrint("%s", "ERROR: wrong options\n");
1053
      exit(EXIT_FAILURE);
S
TD-1057  
Shengliang Guan 已提交
1054 1055
    }
  }
1056

1057
  if (((arguments->debug_print) && (arguments->metaFile == NULL))
1058
          || arguments->verbose_print) {
1059
    printf("###################################################################\n");
1060
    printf("# meta file:                         %s\n", arguments->metaFile);
1061
    printf("# Server IP:                         %s:%hu\n",
1062 1063
            arguments->host == NULL ? "localhost" : arguments->host,
            arguments->port );
1064 1065
    printf("# User:                              %s\n", arguments->user);
    printf("# Password:                          %s\n", arguments->password);
1066 1067
    printf("# Use metric:                        %s\n",
            arguments->use_metric ? "true" : "false");
1068
    if (*(arguments->datatype)) {
1069 1070 1071 1072 1073 1074 1075
        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");
1076
    }
1077
    printf("# Insertion interval:                %"PRIu64"\n",
1078
            arguments->insert_interval);
1079
    printf("# Number of records per req:         %ud\n",
1080
            arguments->num_of_RPR);
1081
    printf("# Max SQL length:                    %"PRIu64"\n",
1082
            arguments->max_sql_len);
1083
    printf("# Length of Binary:                  %d\n", arguments->len_of_binary);
1084
    printf("# Number of Threads:                 %d\n", arguments->num_of_threads);
1085
    printf("# Number of Tables:                  %"PRId64"\n",
1086
            arguments->num_of_tables);
1087
    printf("# Number of Data per Table:          %"PRId64"\n",
1088
            arguments->num_of_DPT);
1089 1090 1091 1092 1093
    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);
1094

1095 1096 1097 1098
    }
    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);
1099
    printf("# Print verbose info:                %d\n", arguments->verbose_print);
1100
    printf("###################################################################\n");
1101 1102

    prompt();
1103
  }
1104
}
H
hzcheng 已提交
1105

1106 1107
static bool getInfoFromJsonFile(char* file);
static void init_rand_data();
1108
static void tmfclose(FILE *fp) {
1109 1110 1111 1112
  if (NULL != fp) {
    fclose(fp);
  }
}
1113

1114
static void tmfree(char *buf) {
1115 1116
  if (NULL != buf) {
    free(buf);
H
Hui Li 已提交
1117
  }
1118
}
H
Hui Li 已提交
1119

1120
static int queryDbExec(TAOS *taos, char *command, QUERY_TYPE type, bool quiet) {
1121 1122 1123
  int i;
  TAOS_RES *res = NULL;
  int32_t   code = -1;
1124

S
Shuduo Sang 已提交
1125
  for (i = 0; i < 5 /* retry */; i++) {
1126 1127 1128
    if (NULL != res) {
      taos_free_result(res);
      res = NULL;
H
hzcheng 已提交
1129
    }
1130

1131 1132 1133 1134
    res = taos_query(taos, command);
    code = taos_errno(res);
    if (0 == code) {
      break;
1135
    }
H
hzcheng 已提交
1136 1137
  }

1138
  verbosePrint("%s() LN%d - command: %s\n", __func__, __LINE__, command);
1139
  if (code != 0) {
1140
    if (!quiet) {
1141 1142
      errorPrint("Failed to execute %s, reason: %s\n",
              command, taos_errstr(res));
1143
    }
1144 1145 1146
    taos_free_result(res);
    //taos_close(taos);
    return -1;
1147
  }
H
hzcheng 已提交
1148

1149 1150 1151 1152
  if (INSERT_TYPE == type) {
    int affectedRows = taos_affected_rows(res);
    taos_free_result(res);
    return affectedRows;
H
hzcheng 已提交
1153
  }
1154

1155
  taos_free_result(res);
1156 1157
  return 0;
}
H
hzcheng 已提交
1158

1159
static void appendResultBufToFile(char *resultBuf, threadInfo *pThreadInfo)
1160
{
1161 1162
  pThreadInfo->fp = fopen(pThreadInfo->filePath, "at");
  if (pThreadInfo->fp == NULL) {
1163 1164
      errorPrint(
              "%s() LN%d, failed to open result file: %s, result will not save to file\n",
1165
              __func__, __LINE__, pThreadInfo->filePath);
1166 1167 1168
      return;
  }

1169 1170 1171
  fprintf(pThreadInfo->fp, "%s", resultBuf);
  tmfclose(pThreadInfo->fp);
  pThreadInfo->fp = NULL;
1172 1173
}

1174
static void fetchResult(TAOS_RES *res, threadInfo* pThreadInfo) {
1175 1176 1177 1178 1179
  TAOS_ROW    row = NULL;
  int         num_rows = 0;
  int         num_fields = taos_field_count(res);
  TAOS_FIELD *fields     = taos_fetch_fields(res);

1180 1181
  char* databuf = (char*) calloc(1, 100*1024*1024);
  if (databuf == NULL) {
1182 1183
    errorPrint("%s() LN%d, failed to malloc, warning: save result to file slowly!\n",
            __func__, __LINE__);
1184 1185
    return ;
  }
H
hzcheng 已提交
1186

1187 1188
  int   totalLen = 0;
  char  temp[16000];
H
hzcheng 已提交
1189

1190
  // fetch the records row by row
1191
  while((row = taos_fetch_row(res))) {
1192
    if ((strlen(pThreadInfo->filePath) > 0)
1193
            && (totalLen >= 100*1024*1024 - 32000)) {
1194
        appendResultBufToFile(databuf, pThreadInfo);
1195 1196
        totalLen = 0;
        memset(databuf, 0, 100*1024*1024);
H
hzcheng 已提交
1197
    }
1198 1199 1200 1201 1202 1203
    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 已提交
1204 1205
  }

1206
  verbosePrint("%s() LN%d, databuf=%s resultFile=%s\n",
1207 1208 1209
          __func__, __LINE__, databuf, pThreadInfo->filePath);
  if (strlen(pThreadInfo->filePath) > 0) {
    appendResultBufToFile(databuf, pThreadInfo);
1210
  }
1211 1212
  free(databuf);
}
H
hzcheng 已提交
1213

1214
static void selectAndGetResult(
1215 1216
        threadInfo *pThreadInfo, char *command)
{
1217 1218 1219 1220 1221 1222 1223 1224 1225
  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;
    }

1226
    fetchResult(res, pThreadInfo);
1227
    taos_free_result(res);
1228

1229 1230 1231
  } else if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) {
      int retCode = postProceSql(
              g_queryInfo.host, &(g_queryInfo.serv_addr), g_queryInfo.port,
1232
              command,
1233
              pThreadInfo);
1234 1235 1236 1237 1238 1239 1240 1241
      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);
  }
1242
}
H
hzcheng 已提交
1243

1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282
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;
1283
  return randfloat[cursor];
1284 1285
}

1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302
#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

1303
static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
1304

1305
static void rand_string(char *str, int size) {
1306 1307 1308 1309
  str[0] = 0;
  if (size > 0) {
    //--size;
    int n;
1310
    for (n = 0; n < size; n++) {
1311
      int key = abs(rand_tinyint()) % (int)(sizeof(charset) - 1);
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
      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++){
1328 1329 1330 1331
    randint[i] = (int)(taosRandom() % 65535);
    randbigint[i] = (int64_t)(taosRandom() % 2147483648);
    randfloat[i] = (float)(taosRandom() / 1000.0);
    randdouble[i] = (double)(taosRandom() / 1000000.0);
1332 1333 1334
  }
}

1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354
#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)

1355
static int printfInsertMeta() {
1356
    SHOW_PARSE_RESULT_START();
1357

1358
  printf("interface:                  \033[33m%s\033[0m\n",
S
Shuduo Sang 已提交
1359
          (g_args.iface==TAOSC_IFACE)?"taosc":(g_args.iface==REST_IFACE)?"rest":"stmt");
1360 1361
  printf("host:                       \033[33m%s:%u\033[0m\n",
          g_Dbs.host, g_Dbs.port);
1362 1363
  printf("user:                       \033[33m%s\033[0m\n", g_Dbs.user);
  printf("password:                   \033[33m%s\033[0m\n", g_Dbs.password);
1364
  printf("configDir:                  \033[33m%s\033[0m\n", configDir);
1365 1366
  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);
1367 1368
  printf("thread num of create table: \033[33m%d\033[0m\n",
          g_Dbs.threadCountByCreateTbl);
1369
  printf("top insert interval:        \033[33m%"PRIu64"\033[0m\n",
1370
          g_args.insert_interval);
1371
  printf("number of records per req:  \033[33m%ud\033[0m\n",
1372
          g_args.num_of_RPR);
1373
  printf("max sql length:             \033[33m%"PRIu64"\033[0m\n",
1374
          g_args.max_sql_len);
1375 1376

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

1378 1379
  for (int i = 0; i < g_Dbs.dbCount; i++) {
    printf("database[\033[33m%d\033[0m]:\n", i);
1380 1381
    printf("  database[%d] name:      \033[33m%s\033[0m\n",
            i, g_Dbs.db[i].dbName);
1382
    if (0 == g_Dbs.db[i].drop) {
1383 1384 1385
      printf("  drop:                  \033[33mno\033[0m\n");
    } else {
      printf("  drop:                  \033[33myes\033[0m\n");
1386 1387 1388
    }

    if (g_Dbs.db[i].dbCfg.blocks > 0) {
1389 1390
      printf("  blocks:                \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.blocks);
1391 1392
    }
    if (g_Dbs.db[i].dbCfg.cache > 0) {
1393 1394
      printf("  cache:                 \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.cache);
1395 1396
    }
    if (g_Dbs.db[i].dbCfg.days > 0) {
1397 1398
      printf("  days:                  \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.days);
1399 1400
    }
    if (g_Dbs.db[i].dbCfg.keep > 0) {
1401 1402
      printf("  keep:                  \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.keep);
1403 1404
    }
    if (g_Dbs.db[i].dbCfg.replica > 0) {
1405 1406
      printf("  replica:               \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.replica);
1407 1408
    }
    if (g_Dbs.db[i].dbCfg.update > 0) {
1409 1410
      printf("  update:                \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.update);
1411 1412
    }
    if (g_Dbs.db[i].dbCfg.minRows > 0) {
1413 1414
      printf("  minRows:               \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.minRows);
1415 1416
    }
    if (g_Dbs.db[i].dbCfg.maxRows > 0) {
1417 1418
      printf("  maxRows:               \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.maxRows);
1419 1420 1421 1422 1423
    }
    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) {
1424 1425
      printf("  walLevel:              \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.walLevel);
1426 1427
    }
    if (g_Dbs.db[i].dbCfg.fsync > 0) {
1428 1429
      printf("  fsync:                 \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.fsync);
1430 1431
    }
    if (g_Dbs.db[i].dbCfg.quorum > 0) {
1432 1433
      printf("  quorum:                \033[33m%d\033[0m\n",
              g_Dbs.db[i].dbCfg.quorum);
1434 1435
    }
    if (g_Dbs.db[i].dbCfg.precision[0] != 0) {
1436
      if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
1437
              || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) {
1438
        printf("  precision:             \033[33m%s\033[0m\n",
1439
            g_Dbs.db[i].dbCfg.precision);
1440
      } else {
1441
        printf("\033[1m\033[40;31m  precision error:       %s\033[0m\n",
1442
                g_Dbs.db[i].dbCfg.precision);
1443
        return -1;
1444 1445 1446
      }
    }

1447
    printf("  super table count:     \033[33m%"PRIu64"\033[0m\n",
1448
        g_Dbs.db[i].superTblCount);
1449 1450
    for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) {
      printf("  super table[\033[33m%"PRIu64"\033[0m]:\n", j);
1451

1452
      printf("      stbName:           \033[33m%s\033[0m\n",
1453
          g_Dbs.db[i].superTbls[j].sTblName);
1454 1455 1456 1457 1458 1459 1460 1461

      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");
      }
1462

1463 1464 1465 1466 1467 1468 1469
      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");
      }
1470

1471
      printf("      childTblCount:     \033[33m%"PRId64"\033[0m\n",
1472
              g_Dbs.db[i].superTbls[j].childTblCount);
1473
      printf("      childTblPrefix:    \033[33m%s\033[0m\n",
1474
              g_Dbs.db[i].superTbls[j].childTblPrefix);
1475
      printf("      dataSource:        \033[33m%s\033[0m\n",
1476
              g_Dbs.db[i].superTbls[j].dataSource);
1477 1478 1479
      printf("      iface:             \033[33m%s\033[0m\n",
          (g_Dbs.db[i].superTbls[j].iface==TAOSC_IFACE)?"taosc":
          (g_Dbs.db[i].superTbls[j].iface==REST_IFACE)?"rest":"stmt");
1480
      if (g_Dbs.db[i].superTbls[j].childTblLimit > 0) {
1481
        printf("      childTblLimit:     \033[33m%"PRId64"\033[0m\n",
1482
                g_Dbs.db[i].superTbls[j].childTblLimit);
1483
      }
1484
      if (g_Dbs.db[i].superTbls[j].childTblOffset > 0) {
1485
        printf("      childTblOffset:    \033[33m%"PRIu64"\033[0m\n",
1486
                g_Dbs.db[i].superTbls[j].childTblOffset);
1487
      }
1488
      printf("      insertRows:        \033[33m%"PRId64"\033[0m\n",
1489
              g_Dbs.db[i].superTbls[j].insertRows);
1490
/*
1491
      if (0 == g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl) {
1492
        printf("      multiThreadWriteOneTbl:  \033[33mno\033[0m\n");
1493
      }else {
1494
        printf("      multiThreadWriteOneTbl:  \033[33myes\033[0m\n");
1495
      }
1496
      */
1497
      printf("      interlaceRows:     \033[33m%ud\033[0m\n",
1498
              g_Dbs.db[i].superTbls[j].interlaceRows);
1499 1500

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

1505
      printf("      disorderRange:     \033[33m%d\033[0m\n",
1506
              g_Dbs.db[i].superTbls[j].disorderRange);
1507
      printf("      disorderRatio:     \033[33m%d\033[0m\n",
1508
              g_Dbs.db[i].superTbls[j].disorderRatio);
1509
      printf("      maxSqlLen:         \033[33m%"PRIu64"\033[0m\n",
1510
              g_Dbs.db[i].superTbls[j].maxSqlLen);
1511
      printf("      timeStampStep:     \033[33m%"PRId64"\033[0m\n",
1512
              g_Dbs.db[i].superTbls[j].timeStampStep);
1513
      printf("      startTimestamp:    \033[33m%s\033[0m\n",
1514
              g_Dbs.db[i].superTbls[j].startTimestamp);
1515
      printf("      sampleFormat:      \033[33m%s\033[0m\n",
1516
              g_Dbs.db[i].superTbls[j].sampleFormat);
1517
      printf("      sampleFile:        \033[33m%s\033[0m\n",
1518
              g_Dbs.db[i].superTbls[j].sampleFile);
1519
      printf("      tagsFile:          \033[33m%s\033[0m\n",
1520
              g_Dbs.db[i].superTbls[j].tagsFile);
1521
      printf("      columnCount:       \033[33m%d\033[0m\n",
1522
              g_Dbs.db[i].superTbls[j].columnCount);
1523 1524
      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);
1525
        if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType,
1526 1527 1528
                       "binary", 6))
                || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType,
                       "nchar", 5))) {
1529
          printf("column[\033[33m%d\033[0m]:\033[33m%s(%d)\033[0m ", k,
1530 1531
                  g_Dbs.db[i].superTbls[j].columns[k].dataType,
                  g_Dbs.db[i].superTbls[j].columns[k].dataLen);
1532
        } else {
1533
          printf("column[%d]:\033[33m%s\033[0m ", k,
1534
                  g_Dbs.db[i].superTbls[j].columns[k].dataType);
1535 1536 1537
        }
      }
      printf("\n");
1538 1539

      printf("      tagCount:            \033[33m%d\033[0m\n        ",
1540
              g_Dbs.db[i].superTbls[j].tagCount);
1541 1542
      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);
1543
        if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
1544 1545 1546
                        "binary", strlen("binary")))
                || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
                        "nchar", strlen("nchar")))) {
1547
          printf("tag[%d]:\033[33m%s(%d)\033[0m ", k,
1548 1549
                  g_Dbs.db[i].superTbls[j].tags[k].dataType,
                  g_Dbs.db[i].superTbls[j].tags[k].dataLen);
1550
        } else {
1551
          printf("tag[%d]:\033[33m%s\033[0m ", k,
1552
                  g_Dbs.db[i].superTbls[j].tags[k].dataType);
1553
        }
1554 1555 1556 1557 1558
      }
      printf("\n");
    }
    printf("\n");
  }
1559 1560

  SHOW_PARSE_RESULT_END();
1561 1562

  return 0;
1563 1564 1565
}

static void printfInsertMetaToFile(FILE* fp) {
1566 1567

  SHOW_PARSE_RESULT_START_TO_FILE(fp);
1568

1569 1570
  fprintf(fp, "host:                       %s:%u\n", g_Dbs.host, g_Dbs.port);
  fprintf(fp, "user:                       %s\n", g_Dbs.user);
1571
  fprintf(fp, "configDir:                  %s\n", configDir);
1572 1573 1574
  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);
1575
  fprintf(fp, "number of records per req:  %ud\n", g_args.num_of_RPR);
1576
  fprintf(fp, "max sql length:             %"PRIu64"\n", g_args.max_sql_len);
1577
  fprintf(fp, "database count:          %d\n", g_Dbs.dbCount);
1578

1579 1580
  for (int i = 0; i < g_Dbs.dbCount; i++) {
    fprintf(fp, "database[%d]:\n", i);
1581
    fprintf(fp, "  database[%d] name:       %s\n", i, g_Dbs.db[i].dbName);
1582
    if (0 == g_Dbs.db[i].drop) {
1583
      fprintf(fp, "  drop:                  no\n");
1584
    }else {
1585
      fprintf(fp, "  drop:                  yes\n");
1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
    }

    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) {
1625
      if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", 2))
1626
              || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) {
1627 1628
        fprintf(fp, "  precision:             %s\n",
                g_Dbs.db[i].dbCfg.precision);
1629
      } else {
1630 1631
        fprintf(fp, "  precision error:       %s\n",
                g_Dbs.db[i].dbCfg.precision);
1632 1633 1634
      }
    }

1635 1636
    fprintf(fp, "  super table count:     %"PRIu64"\n",
            g_Dbs.db[i].superTblCount);
1637 1638
    for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
      fprintf(fp, "  super table[%d]:\n", j);
1639

1640 1641
      fprintf(fp, "      stbName:           %s\n",
              g_Dbs.db[i].superTbls[j].sTblName);
1642 1643 1644

      if (PRE_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable) {
        fprintf(fp, "      autoCreateTable:   %s\n",  "no");
1645 1646
      } else if (AUTO_CREATE_SUBTBL
              == g_Dbs.db[i].superTbls[j].autoCreateTable) {
1647 1648 1649 1650
        fprintf(fp, "      autoCreateTable:   %s\n",  "yes");
      } else {
        fprintf(fp, "      autoCreateTable:   %s\n",  "error");
      }
1651

1652 1653
      if (TBL_NO_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists) {
        fprintf(fp, "      childTblExists:    %s\n",  "no");
1654 1655
      } else if (TBL_ALREADY_EXISTS
              == g_Dbs.db[i].superTbls[j].childTblExists) {
1656 1657 1658 1659
        fprintf(fp, "      childTblExists:    %s\n",  "yes");
      } else {
        fprintf(fp, "      childTblExists:    %s\n",  "error");
      }
1660

1661
      fprintf(fp, "      childTblCount:     %"PRId64"\n",
1662 1663 1664 1665 1666
              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);
1667 1668 1669
      fprintf(fp, "      iface:             %s\n",
          (g_Dbs.db[i].superTbls[j].iface==TAOSC_IFACE)?"taosc":
          (g_Dbs.db[i].superTbls[j].iface==REST_IFACE)?"rest":"stmt");
1670
      fprintf(fp, "      insertRows:        %"PRId64"\n",
1671
              g_Dbs.db[i].superTbls[j].insertRows);
1672
      fprintf(fp, "      interlace rows:    %ud\n",
1673
              g_Dbs.db[i].superTbls[j].interlaceRows);
1674
      if (g_Dbs.db[i].superTbls[j].interlaceRows > 0) {
1675
        fprintf(fp, "      stable insert interval:   %"PRIu64"\n",
1676
                g_Dbs.db[i].superTbls[j].insertInterval);
1677
      }
1678
/*
1679
      if (0 == g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl) {
1680
        fprintf(fp, "      multiThreadWriteOneTbl:  no\n");
1681
      }else {
1682
        fprintf(fp, "      multiThreadWriteOneTbl:  yes\n");
1683
      }
1684
      */
1685
      fprintf(fp, "      interlaceRows:     %ud\n",
1686
              g_Dbs.db[i].superTbls[j].interlaceRows);
1687 1688 1689 1690
      fprintf(fp, "      disorderRange:     %d\n",
              g_Dbs.db[i].superTbls[j].disorderRange);
      fprintf(fp, "      disorderRatio:     %d\n",
              g_Dbs.db[i].superTbls[j].disorderRatio);
1691
      fprintf(fp, "      maxSqlLen:         %"PRIu64"\n",
1692
              g_Dbs.db[i].superTbls[j].maxSqlLen);
1693

1694 1695 1696 1697
      fprintf(fp, "      timeStampStep:     %"PRId64"\n",
              g_Dbs.db[i].superTbls[j].timeStampStep);
      fprintf(fp, "      startTimestamp:    %s\n",
              g_Dbs.db[i].superTbls[j].startTimestamp);
1698 1699 1700 1701 1702 1703
      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);
1704

1705 1706
      fprintf(fp, "      columnCount:       %d\n        ",
              g_Dbs.db[i].superTbls[j].columnCount);
1707 1708
      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);
1709
        if ((0 == strncasecmp(
1710 1711
                        g_Dbs.db[i].superTbls[j].columns[k].dataType,
                        "binary", strlen("binary")))
1712 1713
                || (0 == strncasecmp(
                        g_Dbs.db[i].superTbls[j].columns[k].dataType,
1714
                        "nchar", strlen("nchar")))) {
1715 1716 1717
          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);
1718
        } else {
1719 1720
          fprintf(fp, "column[%d]:%s ",
                  k, g_Dbs.db[i].superTbls[j].columns[k].dataType);
1721 1722 1723
        }
      }
      fprintf(fp, "\n");
1724 1725 1726

      fprintf(fp, "      tagCount:            %d\n        ",
              g_Dbs.db[i].superTbls[j].tagCount);
1727 1728
      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);
1729
        if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
1730 1731 1732
                        "binary", strlen("binary")))
                || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType,
                        "nchar", strlen("nchar")))) {
1733 1734
          fprintf(fp, "tag[%d]:%s(%d) ",
                  k, g_Dbs.db[i].superTbls[j].tags[k].dataType,
1735
                  g_Dbs.db[i].superTbls[j].tags[k].dataLen);
1736 1737
        } else {
          fprintf(fp, "tag[%d]:%s ", k, g_Dbs.db[i].superTbls[j].tags[k].dataType);
1738
        }
1739 1740 1741 1742 1743
      }
      fprintf(fp, "\n");
    }
    fprintf(fp, "\n");
  }
1744

1745
  SHOW_PARSE_RESULT_END_TO_FILE(fp);
1746 1747 1748
}

static void printfQueryMeta() {
1749

1750
  SHOW_PARSE_RESULT_START();
1751

1752
  printf("host:                    \033[33m%s:%u\033[0m\n",
1753
          g_queryInfo.host, g_queryInfo.port);
1754 1755 1756 1757
  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");
1758 1759 1760 1761

  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",
1762
      g_queryInfo.specifiedQueryInfo.sqlCount);
1763 1764 1765
    if (g_queryInfo.specifiedQueryInfo.sqlCount > 0) {
      printf("specified tbl query times:\n");
      printf("                \033[33m%"PRIu64"\033[0m\n",
1766
      g_queryInfo.specifiedQueryInfo.queryTimes);
1767 1768 1769
      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);
1770
      printf("concurrent:     \033[33m%d\033[0m\n",
1771 1772
      g_queryInfo.specifiedQueryInfo.concurrent);
      printf("mod:            \033[33m%s\033[0m\n",
1773
        (g_queryInfo.specifiedQueryInfo.asyncMode)?"async":"sync");
1774
      printf("interval:       \033[33m%"PRIu64"\033[0m\n",
1775
        g_queryInfo.specifiedQueryInfo.subscribeInterval);
1776
      printf("restart:        \033[33m%d\033[0m\n",
1777
        g_queryInfo.specifiedQueryInfo.subscribeRestart);
1778
      printf("keepProgress:   \033[33m%d\033[0m\n",
1779
        g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
1780

1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796
      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);
1797
      printf("childTblCount:  \033[33m%"PRId64"\033[0m\n",
1798 1799 1800 1801 1802 1803 1804
        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",
1805
        (g_queryInfo.superQueryInfo.asyncMode)?"async":"sync");
1806
      printf("interval:       \033[33m%"PRIu64"\033[0m\n",
1807
        g_queryInfo.superQueryInfo.subscribeInterval);
1808
      printf("restart:        \033[33m%d\033[0m\n",
1809
        g_queryInfo.superQueryInfo.subscribeRestart);
1810
      printf("keepProgress:   \033[33m%d\033[0m\n",
1811
        g_queryInfo.superQueryInfo.subscribeKeepProgress);
1812

1813 1814 1815 1816 1817 1818
      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");
    }
1819
  }
1820

1821
  SHOW_PARSE_RESULT_END();
1822 1823
}

1824
static char* formatTimestamp(char* buf, int64_t val, int precision) {
1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855
  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;
}

1856
static void xDumpFieldToFile(FILE* fp, const char* val,
1857
        TAOS_FIELD* field, int32_t length, int precision) {
1858

1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893
  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:
1894
      formatTimestamp(buf, *(int64_t*)val, precision);
1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909
      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) {
1910
    errorPrint("%s() LN%d, failed to open file: %s\n", __func__, __LINE__, fname);
1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924
    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);
1925

1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945
  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;
}

1946 1947
static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) {
  TAOS_RES * res;
1948 1949
  TAOS_ROW row = NULL;
  int count = 0;
1950 1951

  res = taos_query(taos, "show databases;");
1952
  int32_t code = taos_errno(res);
1953

1954
  if (code != 0) {
1955
    errorPrint( "failed to run <show databases>, reason: %s\n", taos_errstr(res));
1956 1957 1958 1959 1960
    return -1;
  }

  TAOS_FIELD *fields = taos_fetch_fields(res);

1961
  while((row = taos_fetch_row(res)) != NULL) {
1962
    // sys database name : 'log'
1963
    if (strncasecmp(row[TSDB_SHOW_DB_NAME_INDEX], "log",
1964
                fields[TSDB_SHOW_DB_NAME_INDEX].bytes) == 0) {
1965 1966
      continue;
    }
1967 1968 1969

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

1974
    tstrncpy(dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX],
1975
            fields[TSDB_SHOW_DB_NAME_INDEX].bytes);
1976
    formatTimestamp(dbInfos[count]->create_time,
1977 1978
            *(int64_t*)row[TSDB_SHOW_DB_CREATED_TIME_INDEX],
            TSDB_TIME_PRECISION_MILLI);
S
Shuduo Sang 已提交
1979
    dbInfos[count]->ntables = *((int64_t *)row[TSDB_SHOW_DB_NTABLES_INDEX]);
1980
    dbInfos[count]->vgroups = *((int32_t *)row[TSDB_SHOW_DB_VGROUPS_INDEX]);
1981 1982
    dbInfos[count]->replica = *((int16_t *)row[TSDB_SHOW_DB_REPLICA_INDEX]);
    dbInfos[count]->quorum = *((int16_t *)row[TSDB_SHOW_DB_QUORUM_INDEX]);
1983
    dbInfos[count]->days = *((int16_t *)row[TSDB_SHOW_DB_DAYS_INDEX]);
1984

1985
    tstrncpy(dbInfos[count]->keeplist, (char *)row[TSDB_SHOW_DB_KEEP_INDEX],
1986
            fields[TSDB_SHOW_DB_KEEP_INDEX].bytes);
1987 1988 1989 1990 1991 1992 1993
    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]));
1994
    dbInfos[count]->cachelast =
1995
      (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_CACHELAST_INDEX]));
1996

1997
    tstrncpy(dbInfos[count]->precision,
1998 1999
            (char *)row[TSDB_SHOW_DB_PRECISION_INDEX],
            fields[TSDB_SHOW_DB_PRECISION_INDEX].bytes);
2000
    dbInfos[count]->update = *((int8_t *)row[TSDB_SHOW_DB_UPDATE_INDEX]);
2001
    tstrncpy(dbInfos[count]->status, (char *)row[TSDB_SHOW_DB_STATUS_INDEX],
2002
            fields[TSDB_SHOW_DB_STATUS_INDEX].bytes);
2003

2004 2005
    count++;
    if (count > MAX_DATABASE_COUNT) {
2006
      errorPrint("%s() LN%d, The database count overflow than %d\n",
2007
         __func__, __LINE__, MAX_DATABASE_COUNT);
2008 2009 2010 2011 2012 2013 2014
      break;
    }
  }

  return count;
}

2015
static void printfDbInfoForQueryToFile(
2016
        char* filename, SDbInfo* dbInfos, int index) {
2017

2018
  if (filename[0] == 0)
2019
      return;
2020 2021 2022

  FILE *fp = fopen(filename, "at");
  if (fp == NULL) {
2023
    errorPrint( "failed to open file: %s\n", filename);
2024
    return;
2025 2026 2027 2028 2029
  }

  fprintf(fp, "================ database[%d] ================\n", index);
  fprintf(fp, "name: %s\n", dbInfos->name);
  fprintf(fp, "created_time: %s\n", dbInfos->create_time);
S
Shuduo Sang 已提交
2030
  fprintf(fp, "ntables: %"PRId64"\n", dbInfos->ntables);
2031
  fprintf(fp, "vgroups: %d\n", dbInfos->vgroups);
2032 2033
  fprintf(fp, "replica: %d\n", dbInfos->replica);
  fprintf(fp, "quorum: %d\n", dbInfos->quorum);
2034 2035
  fprintf(fp, "days: %d\n", dbInfos->days);
  fprintf(fp, "keep0,keep1,keep(D): %s\n", dbInfos->keeplist);
2036 2037 2038 2039 2040 2041 2042
  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);
2043 2044
  fprintf(fp, "cachelast: %d\n", dbInfos->cachelast);
  fprintf(fp, "precision: %s\n", dbInfos->precision);
2045
  fprintf(fp, "update: %d\n", dbInfos->update);
2046
  fprintf(fp, "status: %s\n", dbInfos->status);
2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060
  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);
2061
  snprintf(filename, MAX_QUERY_SQL_LENGTH, "querySystemInfo-%d-%d-%d %d:%d:%d",
2062 2063
          lt->tm_year+1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min,
          lt->tm_sec);
2064

2065 2066
  // show variables
  res = taos_query(taos, "show variables;");
2067
  //fetchResult(res, filename);
2068 2069 2070 2071 2072
  xDumpResultToFile(filename, res);

  // show dnodes
  res = taos_query(taos, "show dnodes;");
  xDumpResultToFile(filename, res);
2073
  //fetchResult(res, filename);
2074

2075 2076 2077 2078
  // show databases
  res = taos_query(taos, "show databases;");
  SDbInfo** dbInfos = (SDbInfo **)calloc(MAX_DATABASE_COUNT, sizeof(SDbInfo *));
  if (dbInfos == NULL) {
2079
    errorPrint("%s() LN%d, failed to allocate memory\n", __func__, __LINE__);
2080 2081 2082
    return;
  }
  int dbCount = getDbFromServer(taos, dbInfos);
2083
  if (dbCount <= 0) {
2084 2085
      free(dbInfos);
      return;
2086
  }
2087 2088

  for (int i = 0; i < dbCount; i++) {
2089
    // printf database info
2090
    printfDbInfoForQueryToFile(filename, dbInfos[i], i);
2091

2092 2093 2094 2095
    // show db.vgroups
    snprintf(buffer, MAX_QUERY_SQL_LENGTH, "show %s.vgroups;", dbInfos[i]->name);
    res = taos_query(taos, buffer);
    xDumpResultToFile(filename, res);
2096

2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107
    // 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);
}

2108
static int postProceSql(char *host, struct sockaddr_in *pServAddr, uint16_t port,
2109
        char* sqlstr, threadInfo *pThreadInfo)
2110
{
2111
    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";
2112

2113
    char *url = "/rest/sql";
2114

2115 2116 2117 2118
    int bytes, sent, received, req_str_len, resp_len;
    char *request_buf;
    char response_buf[RESP_BUF_LEN];
    uint16_t rest_port = port + TSDB_PORT_HTTP;
2119

2120
    int req_buf_len = strlen(sqlstr) + REQ_EXTRA_BUF_LEN;
2121

2122 2123 2124 2125 2126
    request_buf = malloc(req_buf_len);
    if (NULL == request_buf) {
      errorPrint("%s", "ERROR, cannot allocate memory.\n");
      exit(EXIT_FAILURE);
    }
2127

2128 2129
    char userpass_buf[INPUT_BUF_LEN];
    int mod_table[] = {0, 2, 1};
2130

2131 2132 2133 2134 2135 2136 2137 2138
    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', '+', '/'};
2139

2140 2141 2142 2143
    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);
2144

2145
    char base64_buf[INPUT_BUF_LEN];
2146
#ifdef WINDOWS
2147
    WSADATA wsaData;
2148
    WSAStartup(MAKEWORD(2, 2), &wsaData);
2149 2150
    SOCKET sockfd;
#else
2151
    int sockfd;
2152
#endif
2153 2154
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
2155
#ifdef WINDOWS
2156
        errorPrint( "Could not create socket : %d" , WSAGetLastError());
2157
#endif
2158 2159 2160 2161
        debugPrint("%s() LN%d, sockfd=%d\n", __func__, __LINE__, sockfd);
        free(request_buf);
        ERROR_EXIT("ERROR opening socket");
    }
2162

2163
    int retConn = connect(sockfd, (struct sockaddr *)pServAddr, sizeof(struct sockaddr));
2164 2165 2166 2167 2168
    debugPrint("%s() LN%d connect() return %d\n", __func__, __LINE__, retConn);
    if (retConn < 0) {
        free(request_buf);
        ERROR_EXIT("ERROR connecting");
    }
2169

2170
    memset(base64_buf, 0, INPUT_BUF_LEN);
2171

2172 2173 2174 2175 2176 2177 2178 2179
    for (int n = 0, m = 0; n < userpass_buf_len;) {
      uint32_t oct_a = n < userpass_buf_len ?
        (unsigned char) userpass_buf[n++]:0;
      uint32_t oct_b = n < userpass_buf_len ?
        (unsigned char) userpass_buf[n++]:0;
      uint32_t oct_c = n < userpass_buf_len ?
        (unsigned char) userpass_buf[n++]:0;
      uint32_t triple = (oct_a << 0x10) + (oct_b << 0x08) + oct_c;
2180

2181 2182 2183 2184 2185
      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];
    }
2186

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

2190 2191 2192
    debugPrint("%s() LN%d: auth string base64 encoded: %s\n",
            __func__, __LINE__, base64_buf);
    char *auth = base64_buf;
2193

2194 2195 2196 2197 2198 2199 2200 2201 2202
    int r = snprintf(request_buf,
            req_buf_len,
            req_fmt, url, host, rest_port,
            auth, strlen(sqlstr), sqlstr);
    if (r >= req_buf_len) {
        free(request_buf);
        ERROR_EXIT("ERROR too long request");
    }
    verbosePrint("%s() LN%d: Request:\n%s\n", __func__, __LINE__, request_buf);
2203

2204 2205 2206
    req_str_len = strlen(request_buf);
    sent = 0;
    do {
2207
#ifdef WINDOWS
2208
        bytes = send(sockfd, request_buf + sent, req_str_len - sent, 0);
2209
#else
2210
        bytes = write(sockfd, request_buf + sent, req_str_len - sent);
2211
#endif
2212 2213 2214 2215 2216 2217
        if (bytes < 0)
            ERROR_EXIT("ERROR writing message to socket");
        if (bytes == 0)
            break;
        sent+=bytes;
    } while(sent < req_str_len);
2218

2219 2220 2221 2222
    memset(response_buf, 0, RESP_BUF_LEN);
    resp_len = sizeof(response_buf) - 1;
    received = 0;
    do {
2223
#ifdef WINDOWS
2224
        bytes = recv(sockfd, response_buf + received, resp_len - received, 0);
2225
#else
2226
        bytes = read(sockfd, response_buf + received, resp_len - received);
2227
#endif
2228 2229 2230 2231 2232 2233 2234 2235
        if (bytes < 0) {
            free(request_buf);
            ERROR_EXIT("ERROR reading response from socket");
        }
        if (bytes == 0)
            break;
        received += bytes;
    } while(received < resp_len);
2236

2237 2238 2239 2240
    if (received == resp_len) {
        free(request_buf);
        ERROR_EXIT("ERROR storing complete response from socket");
    }
H
Haojun Liao 已提交
2241

2242 2243
    response_buf[RESP_BUF_LEN - 1] = '\0';
    printf("Response:\n%s\n", response_buf);
H
Haojun Liao 已提交
2244

2245 2246
    if (strlen(pThreadInfo->filePath) > 0) {
       appendResultBufToFile(response_buf, pThreadInfo);
2247 2248
    }

2249
    free(request_buf);
2250
#ifdef WINDOWS
2251
    closesocket(sockfd);
2252 2253
    WSACleanup();
#else
2254
    close(sockfd);
2255
#endif
2256

2257
    return 0;
2258 2259
}

2260
static char* getTagValueFromTagSample(SSuperTable* stbInfo, int tagUsePos) {
2261 2262
  char*  dataBuf = (char*)calloc(TSDB_MAX_SQL_LEN+1, 1);
  if (NULL == dataBuf) {
2263
    errorPrint("%s() LN%d, calloc failed! size:%d\n",
2264
        __func__, __LINE__, TSDB_MAX_SQL_LEN+1);
2265 2266
    return NULL;
  }
2267

2268
  int    dataLen = 0;
2269
  dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2270
          "(%s)", stbInfo->tagDataBuf + stbInfo->lenOfTagOfOneRow * tagUsePos);
2271

2272 2273 2274
  return dataBuf;
}

2275
static char* generateTagVaulesForStb(SSuperTable* stbInfo, int32_t tableSeq) {
2276 2277 2278 2279 2280 2281 2282 2283 2284
  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++) {
2285
    if ((0 == strncasecmp(stbInfo->tags[i].dataType, "binary", strlen("binary")))
2286
            || (0 == strncasecmp(stbInfo->tags[i].dataType, "nchar", strlen("nchar")))) {
2287
      if (stbInfo->tags[i].dataLen > TSDB_MAX_BINARY_LEN) {
2288
        printf("binary or nchar length overflow, max size:%u\n",
2289
                (uint32_t)TSDB_MAX_BINARY_LEN);
2290 2291 2292
        tmfree(dataBuf);
        return NULL;
      }
2293

2294 2295
      int tagBufLen = stbInfo->tags[i].dataLen + 1;
      char* buf = (char*)calloc(tagBufLen, 1);
2296 2297 2298 2299 2300
      if (NULL == buf) {
        printf("calloc failed! size:%d\n", stbInfo->tags[i].dataLen);
        tmfree(dataBuf);
        return NULL;
      }
2301 2302 2303 2304 2305 2306 2307

      if (tableSeq % 2) {
        tstrncpy(buf, "beijing", tagBufLen);
      } else {
        tstrncpy(buf, "shanghai", tagBufLen);
      }
      //rand_string(buf, stbInfo->tags[i].dataLen);
2308
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2309
              "\'%s\', ", buf);
2310
      tmfree(buf);
2311
    } else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2312
                "int", strlen("int"))) {
2313
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2314
              "%d, ", tableSeq);
2315
    } else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2316
                "bigint", strlen("bigint"))) {
2317
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2318
              "%"PRId64", ", rand_bigint());
2319
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2320
                "float", strlen("float"))) {
2321
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2322
              "%f, ", rand_float());
2323
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2324
                "double", strlen("double"))) {
2325
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2326
              "%f, ", rand_double());
2327
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2328
                "smallint", strlen("smallint"))) {
2329
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2330
              "%d, ", rand_smallint());
2331
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2332
                "tinyint", strlen("tinyint"))) {
2333
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2334
              "%d, ", rand_tinyint());
2335
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2336
                "bool", strlen("bool"))) {
2337
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2338
              "%d, ", rand_bool());
2339
    }  else if (0 == strncasecmp(stbInfo->tags[i].dataType,
2340
                "timestamp", strlen("timestamp"))) {
2341
      dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen,
2342
              "%"PRId64", ", rand_bigint());
2343 2344 2345 2346 2347 2348
    }  else {
      printf("No support data type: %s\n", stbInfo->tags[i].dataType);
      tmfree(dataBuf);
      return NULL;
    }
  }
2349

2350
  dataLen -= 2;
2351
  dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, ")");
2352 2353 2354
  return dataBuf;
}

2355
static int calcRowLen(SSuperTable*  superTbls) {
2356 2357
  int colIndex;
  int  lenOfOneRow = 0;
2358

2359 2360
  for (colIndex = 0; colIndex < superTbls->columnCount; colIndex++) {
    char* dataType = superTbls->columns[colIndex].dataType;
2361

2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377
    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;
2378
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
2379
      lenOfOneRow += 42;
2380
    }  else if (strcasecmp(dataType, "TIMESTAMP") == 0) {
2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393
      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;
2394

2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410
    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;
2411
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
2412 2413 2414 2415 2416 2417 2418 2419
      lenOfTagOfOneRow += superTbls->tags[tagIndex].dataLen + 42;
    } else {
      printf("get error tag type : %s\n", dataType);
      exit(-1);
    }
  }

  superTbls->lenOfTagOfOneRow = lenOfTagOfOneRow;
2420

2421 2422 2423 2424
  return 0;
}


2425
static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos,
2426
        char* dbName, char* sTblName, char** childTblNameOfSuperTbl,
2427
        int64_t* childTblCountOfSuperTbl, int64_t limit, uint64_t offset) {
2428

2429
  char command[BUFFER_SIZE] = "\0";
2430 2431
  char limitBuf[100] = "\0";

2432
  TAOS_RES * res;
2433 2434 2435
  TAOS_ROW row = NULL;

  char* childTblName = *childTblNameOfSuperTbl;
2436 2437

  if (offset >= 0) {
2438
    snprintf(limitBuf, 100, " limit %"PRId64" offset %"PRIu64"",
2439
            limit, offset);
2440 2441
  }

2442
  //get all child table name use cmd: select tbname from superTblName;
2443
  snprintf(command, BUFFER_SIZE, "select tbname from %s.%s %s",
2444
          dbName, sTblName, limitBuf);
2445

2446
  res = taos_query(taos, command);
2447 2448 2449 2450
  int32_t code = taos_errno(res);
  if (code != 0) {
    taos_free_result(res);
    taos_close(taos);
2451
    errorPrint("%s() LN%d, failed to run command %s\n",
2452
           __func__, __LINE__, command);
2453 2454 2455
    exit(-1);
  }

2456 2457
  int64_t childTblCount = (limit < 0)?10000:limit;
  int64_t count = 0;
2458 2459 2460
  if (childTblName == NULL) {
    childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN);
    if (NULL ==  childTblName) {
2461 2462 2463 2464
    taos_free_result(res);
        taos_close(taos);
        errorPrint("%s() LN%d, failed to allocate memory!\n", __func__, __LINE__);
        exit(-1);
2465 2466 2467
    }
  }

2468
  char* pTblName = childTblName;
2469
  while((row = taos_fetch_row(res)) != NULL) {
2470
    int32_t* len = taos_fetch_lengths(res);
2471
    tstrncpy(pTblName, (char *)row[0], len[0]+1);
2472 2473 2474
    //printf("==== sub table name: %s\n", pTblName);
    count++;
    if (count >= childTblCount - 1) {
2475
      char *tmp = realloc(childTblName,
2476
              (size_t)childTblCount*1.5*TSDB_TABLE_NAME_LEN+1);
2477 2478 2479
      if (tmp != NULL) {
        childTblName = tmp;
        childTblCount = (int)(childTblCount*1.5);
2480
        memset(childTblName + count*TSDB_TABLE_NAME_LEN, 0,
2481
                (size_t)((childTblCount-count)*TSDB_TABLE_NAME_LEN));
2482 2483
      } else {
        // exit, if allocate more memory failed
2484
        errorPrint("%s() LN%d, realloc fail for save child table name of %s.%s\n",
2485
               __func__, __LINE__, dbName, sTblName);
2486 2487 2488 2489 2490 2491
        tmfree(childTblName);
        taos_free_result(res);
        taos_close(taos);
        exit(-1);
      }
    }
2492
    pTblName = childTblName + count * TSDB_TABLE_NAME_LEN;
2493
  }
2494

2495 2496 2497 2498 2499 2500 2501
  *childTblCountOfSuperTbl = count;
  *childTblNameOfSuperTbl  = childTblName;

  taos_free_result(res);
  return 0;
}

2502
static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName,
2503
        char* sTblName, char** childTblNameOfSuperTbl,
2504
        int64_t* childTblCountOfSuperTbl) {
2505

2506 2507
    return getChildNameOfSuperTableWithLimitAndOffset(taos, dbName, sTblName,
            childTblNameOfSuperTbl, childTblCountOfSuperTbl,
2508
            -1, 0);
2509 2510
}

2511
static int getSuperTableFromServer(TAOS * taos, char* dbName,
2512
        SSuperTable*  superTbls) {
2513

2514
  char command[BUFFER_SIZE] = "\0";
2515
  TAOS_RES * res;
2516 2517
  TAOS_ROW row = NULL;
  int count = 0;
2518

2519
  //get schema use cmd: describe superTblName;
2520
  snprintf(command, BUFFER_SIZE, "describe %s.%s", dbName, superTbls->sTblName);
2521
  res = taos_query(taos, command);
2522 2523 2524
  int32_t code = taos_errno(res);
  if (code != 0) {
    printf("failed to run command %s\n", command);
2525
    taos_free_result(res);
2526 2527 2528 2529 2530 2531
    return -1;
  }

  int tagIndex = 0;
  int columnIndex = 0;
  TAOS_FIELD *fields = taos_fetch_fields(res);
2532
  while((row = taos_fetch_row(res)) != NULL) {
2533 2534 2535
    if (0 == count) {
      count++;
      continue;
2536
    }
2537 2538

    if (strcmp((char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], "TAG") == 0) {
2539
      tstrncpy(superTbls->tags[tagIndex].field,
2540 2541
              (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
              fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
2542
      tstrncpy(superTbls->tags[tagIndex].dataType,
2543 2544
              (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes);
2545 2546 2547
      superTbls->tags[tagIndex].dataLen =
          *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
      tstrncpy(superTbls->tags[tagIndex].note,
2548 2549
              (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
2550
      tagIndex++;
2551
    } else {
2552
      tstrncpy(superTbls->columns[columnIndex].field,
2553 2554
              (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
              fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
2555
      tstrncpy(superTbls->columns[columnIndex].dataType,
2556 2557
              (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes);
2558 2559 2560
      superTbls->columns[columnIndex].dataLen =
          *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
      tstrncpy(superTbls->columns[columnIndex].note,
2561 2562
              (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
              fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573
      columnIndex++;
    }
    count++;
  }

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

  calcRowLen(superTbls);

2574
/*
2575
  if (TBL_ALREADY_EXISTS == superTbls->childTblExists) {
2576
    //get all child table name use cmd: select tbname from superTblName;
2577 2578 2579
    int childTblCount = 10000;
    superTbls->childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN);
    if (superTbls->childTblName == NULL) {
2580
      errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__);
2581 2582
      return -1;
    }
2583
    getAllChildNameOfSuperTable(taos, dbName,
2584 2585 2586
            superTbls->sTblName,
            &superTbls->childTblName,
            &superTbls->childTblCount);
2587
  }
2588
  */
2589 2590 2591
  return 0;
}

H
Haojun Liao 已提交
2592
static int createSuperTable(
2593 2594
        TAOS * taos, char* dbName,
        SSuperTable*  superTbl) {
H
Haojun Liao 已提交
2595

2596
  char command[BUFFER_SIZE] = "\0";
2597

2598 2599 2600 2601 2602
  char cols[STRING_LEN] = "\0";
  int colIndex;
  int len = 0;

  int  lenOfOneRow = 0;
2603 2604 2605

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

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

2613
    if (strcasecmp(dataType, "BINARY") == 0) {
2614
      len += snprintf(cols + len, STRING_LEN - len,
2615 2616
          ", col%d %s(%d)", colIndex, "BINARY",
          superTbl->columns[colIndex].dataLen);
2617
      lenOfOneRow += superTbl->columns[colIndex].dataLen + 3;
2618
    } else if (strcasecmp(dataType, "NCHAR") == 0) {
2619
      len += snprintf(cols + len, STRING_LEN - len,
2620 2621
          ", col%d %s(%d)", colIndex, "NCHAR",
          superTbl->columns[colIndex].dataLen);
2622
      lenOfOneRow += superTbl->columns[colIndex].dataLen + 3;
2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640
    } 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;
2641
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
2642 2643
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "DOUBLE");
      lenOfOneRow += 42;
2644
    }  else if (strcasecmp(dataType, "TIMESTAMP") == 0) {
2645 2646 2647 2648
      len += snprintf(cols + len, STRING_LEN - len, ", col%d %s", colIndex, "TIMESTAMP");
      lenOfOneRow += 21;
    } else {
      taos_close(taos);
2649
      errorPrint("%s() LN%d, config error data type : %s\n",
2650
         __func__, __LINE__, dataType);
2651 2652 2653 2654
      exit(-1);
    }
  }

2655 2656
  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);
2657 2658

  // save for creating child table
2659 2660 2661
  superTbl->colsOfCreateChildTable = (char*)calloc(len+20, 1);
  if (NULL == superTbl->colsOfCreateChildTable) {
    errorPrint("%s() LN%d, Failed when calloc, size:%d",
2662
           __func__, __LINE__, len+1);
2663 2664 2665 2666
    taos_close(taos);
    exit(-1);
  }

2667
  snprintf(superTbl->colsOfCreateChildTable, len+20, "(ts timestamp%s)", cols);
2668
  verbosePrint("%s() LN%d: %s\n",
2669
      __func__, __LINE__, superTbl->colsOfCreateChildTable);
2670

2671 2672
  if (superTbl->tagCount == 0) {
    errorPrint("%s() LN%d, super table tag count is %d\n",
2673
            __func__, __LINE__, superTbl->tagCount);
2674 2675
    return -1;
  }
2676

2677 2678 2679
  char tags[STRING_LEN] = "\0";
  int tagIndex;
  len = 0;
2680

2681 2682 2683 2684
  int lenOfTagOfOneRow = 0;
  len += snprintf(tags + len, STRING_LEN - len, "(");
  for (tagIndex = 0; tagIndex < superTbl->tagCount; tagIndex++) {
    char* dataType = superTbl->tags[tagIndex].dataType;
2685

2686 2687
    if (strcasecmp(dataType, "BINARY") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex,
2688
              "BINARY", superTbl->tags[tagIndex].dataLen);
2689 2690 2691
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "NCHAR") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex,
2692
              "NCHAR", superTbl->tags[tagIndex].dataLen);
2693 2694 2695
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 3;
    } else if (strcasecmp(dataType, "INT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
2696
              "INT");
2697 2698 2699
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 11;
    } else if (strcasecmp(dataType, "BIGINT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
2700
              "BIGINT");
2701 2702 2703
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 21;
    } else if (strcasecmp(dataType, "SMALLINT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
2704
              "SMALLINT");
2705 2706 2707
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 6;
    } else if (strcasecmp(dataType, "TINYINT") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
2708
              "TINYINT");
2709 2710 2711
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 4;
    } else if (strcasecmp(dataType, "BOOL") == 0)  {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
2712
              "BOOL");
2713 2714 2715
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 6;
    } else if (strcasecmp(dataType, "FLOAT") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
2716
              "FLOAT");
2717 2718 2719
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 22;
    } else if (strcasecmp(dataType, "DOUBLE") == 0) {
      len += snprintf(tags + len, STRING_LEN - len, "t%d %s, ", tagIndex,
2720
              "DOUBLE");
2721 2722 2723
      lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 42;
    } else {
      taos_close(taos);
2724
      errorPrint("%s() LN%d, config error tag type : %s\n",
2725
         __func__, __LINE__, dataType);
2726
      exit(-1);
2727 2728
    }
  }
2729 2730 2731 2732 2733 2734 2735

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

  superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow;

  snprintf(command, BUFFER_SIZE,
2736 2737
          "create table if not exists %s.%s (ts timestamp%s) tags %s",
          dbName, superTbl->sTblName, cols, tags);
2738
  if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) {
2739 2740 2741
      errorPrint( "create supertable %s failed!\n\n",
              superTbl->sTblName);
      return -1;
2742 2743
  }
  debugPrint("create supertable %s success!\n\n", superTbl->sTblName);
2744 2745 2746
  return 0;
}

2747
static int createDatabasesAndStables() {
2748 2749 2750 2751
  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) {
2752
    errorPrint( "Failed to connect to TDengine, reason:%s\n", taos_errstr(NULL));
2753
    return -1;
2754 2755 2756
  }
  char command[BUFFER_SIZE] = "\0";

2757
  for (int i = 0; i < g_Dbs.dbCount; i++) {
2758 2759
    if (g_Dbs.db[i].drop) {
      sprintf(command, "drop database if exists %s;", g_Dbs.db[i].dbName);
2760
      if (0 != queryDbExec(taos, command, NO_INSERT_TYPE, false)) {
2761 2762 2763 2764
        taos_close(taos);
        return -1;
      }

2765
      int dataLen = 0;
2766
      dataLen += snprintf(command + dataLen,
2767
          BUFFER_SIZE - dataLen, "create database if not exists %s", g_Dbs.db[i].dbName);
2768

2769 2770
      if (g_Dbs.db[i].dbCfg.blocks > 0) {
        dataLen += snprintf(command + dataLen,
2771
            BUFFER_SIZE - dataLen, " blocks %d", g_Dbs.db[i].dbCfg.blocks);
2772 2773 2774
      }
      if (g_Dbs.db[i].dbCfg.cache > 0) {
        dataLen += snprintf(command + dataLen,
2775
            BUFFER_SIZE - dataLen, " cache %d", g_Dbs.db[i].dbCfg.cache);
2776 2777 2778
      }
      if (g_Dbs.db[i].dbCfg.days > 0) {
        dataLen += snprintf(command + dataLen,
2779
            BUFFER_SIZE - dataLen, " days %d", g_Dbs.db[i].dbCfg.days);
2780 2781 2782
      }
      if (g_Dbs.db[i].dbCfg.keep > 0) {
        dataLen += snprintf(command + dataLen,
2783
            BUFFER_SIZE - dataLen, " keep %d", g_Dbs.db[i].dbCfg.keep);
2784 2785 2786
      }
      if (g_Dbs.db[i].dbCfg.quorum > 1) {
        dataLen += snprintf(command + dataLen,
2787
            BUFFER_SIZE - dataLen, " quorum %d", g_Dbs.db[i].dbCfg.quorum);
2788 2789 2790
      }
      if (g_Dbs.db[i].dbCfg.replica > 0) {
        dataLen += snprintf(command + dataLen,
2791
            BUFFER_SIZE - dataLen, " replica %d", g_Dbs.db[i].dbCfg.replica);
2792 2793 2794
      }
      if (g_Dbs.db[i].dbCfg.update > 0) {
        dataLen += snprintf(command + dataLen,
2795
            BUFFER_SIZE - dataLen, " update %d", g_Dbs.db[i].dbCfg.update);
2796 2797 2798 2799 2800 2801 2802
      }
      //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,
2803
            BUFFER_SIZE - dataLen, " minrows %d", g_Dbs.db[i].dbCfg.minRows);
2804 2805 2806
      }
      if (g_Dbs.db[i].dbCfg.maxRows > 0) {
        dataLen += snprintf(command + dataLen,
2807
            BUFFER_SIZE - dataLen, " maxrows %d", g_Dbs.db[i].dbCfg.maxRows);
2808 2809 2810
      }
      if (g_Dbs.db[i].dbCfg.comp > 0) {
        dataLen += snprintf(command + dataLen,
2811
            BUFFER_SIZE - dataLen, " comp %d", g_Dbs.db[i].dbCfg.comp);
2812 2813 2814
      }
      if (g_Dbs.db[i].dbCfg.walLevel > 0) {
        dataLen += snprintf(command + dataLen,
2815
            BUFFER_SIZE - dataLen, " wal %d", g_Dbs.db[i].dbCfg.walLevel);
2816 2817 2818
      }
      if (g_Dbs.db[i].dbCfg.cacheLast > 0) {
        dataLen += snprintf(command + dataLen,
2819
            BUFFER_SIZE - dataLen, " cachelast %d", g_Dbs.db[i].dbCfg.cacheLast);
2820 2821 2822
      }
      if (g_Dbs.db[i].dbCfg.fsync > 0) {
        dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen,
2823
                " fsync %d", g_Dbs.db[i].dbCfg.fsync);
2824 2825
      }
      if ((0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "ms", strlen("ms")))
2826 2827
              || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision,
                      "us", strlen("us")))) {
2828
        dataLen += snprintf(command + dataLen, BUFFER_SIZE - dataLen,
2829
                " precision \'%s\';", g_Dbs.db[i].dbCfg.precision);
2830 2831 2832 2833 2834 2835 2836 2837
      }

      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);
2838 2839
    }

2840
    debugPrint("%s() LN%d supertbl count:%"PRIu64"\n",
2841
            __func__, __LINE__, g_Dbs.db[i].superTblCount);
2842 2843 2844

    int validStbCount = 0;

S
Shuduo Sang 已提交
2845
    for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) {
2846 2847 2848 2849 2850
      sprintf(command, "describe %s.%s;", g_Dbs.db[i].dbName,
              g_Dbs.db[i].superTbls[j].sTblName);
      ret = queryDbExec(taos, command, NO_INSERT_TYPE, true);

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

2854
        if (0 != ret) {
S
Shuduo Sang 已提交
2855
          errorPrint("create super table %"PRIu64" failed!\n\n", j);
2856
          continue;
2857 2858 2859
        }
      }

2860
      ret = getSuperTableFromServer(taos, g_Dbs.db[i].dbName,
2861
                &g_Dbs.db[i].superTbls[j]);
2862 2863
      if (0 != ret) {
        errorPrint("\nget super table %s.%s info failed!\n\n",
2864
                g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName);
2865
        continue;
2866
      }
2867 2868

      validStbCount ++;
2869
    }
2870 2871

    g_Dbs.db[i].superTblCount = validStbCount;
2872 2873 2874 2875 2876 2877
  }

  taos_close(taos);
  return 0;
}

2878 2879
static void* createTable(void *sarg)
{
2880 2881
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
2882

S
Shuduo Sang 已提交
2883
  uint64_t  lastPrintTime = taosGetTimestampMs();
2884

2885
  int buff_len;
2886
  buff_len = BUFFER_SIZE / 8;
2887

2888
  char *buffer = calloc(buff_len, 1);
2889
  if (buffer == NULL) {
2890
    errorPrint("%s() LN%d, Memory allocated failed!\n", __func__, __LINE__);
2891 2892
    exit(-1);
  }
2893 2894 2895

  int len = 0;
  int batchNum = 0;
2896

2897
  verbosePrint("%s() LN%d: Creating table from %"PRIu64" to %"PRIu64"\n",
2898 2899
          __func__, __LINE__,
          pThreadInfo->start_table_from, pThreadInfo->end_table_to);
2900

2901
  for (uint64_t i = pThreadInfo->start_table_from;
2902
          i <= pThreadInfo->end_table_to; i++) {
2903
    if (0 == g_Dbs.use_metric) {
2904
      snprintf(buffer, buff_len,
2905
              "create table if not exists %s.%s%"PRIu64" %s;",
2906 2907 2908
              pThreadInfo->db_name,
              g_args.tb_prefix, i,
              pThreadInfo->cols);
2909
    } else {
2910 2911
      if (superTblInfo == NULL) {
        errorPrint("%s() LN%d, use metric, but super table info is NULL\n",
2912
                  __func__, __LINE__);
2913
        free(buffer);
2914 2915 2916 2917 2918 2919
        exit(-1);
      } else {
        if (0 == len) {
          batchNum = 0;
          memset(buffer, 0, buff_len);
          len += snprintf(buffer + len,
2920
                  buff_len - len, "create table ");
2921 2922 2923
        }
        char* tagsValBuf = NULL;
        if (0 == superTblInfo->tagSource) {
2924
          tagsValBuf = generateTagVaulesForStb(superTblInfo, i);
2925 2926
        } else {
          tagsValBuf = getTagValueFromTagSample(
2927 2928
                  superTblInfo,
                  i % superTblInfo->tagSampleCount);
2929 2930 2931 2932 2933 2934
        }
        if (NULL == tagsValBuf) {
          free(buffer);
          return NULL;
        }
        len += snprintf(buffer + len,
2935
                buff_len - len,
2936
                "if not exists %s.%s%"PRIu64" using %s.%s tags %s ",
2937 2938 2939
                pThreadInfo->db_name, superTblInfo->childTblPrefix,
                i, pThreadInfo->db_name,
                superTblInfo->sTblName, tagsValBuf);
2940 2941 2942
        free(tagsValBuf);
        batchNum++;
        if ((batchNum < superTblInfo->batchCreateTableNum)
2943 2944
                && ((buff_len - len)
                    >= (superTblInfo->lenOfTagOfOneRow + 256))) {
2945 2946
          continue;
        }
2947 2948 2949 2950
      }
    }

    len = 0;
2951
    if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)){
2952
      errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer);
2953
      free(buffer);
2954 2955 2956
      return NULL;
    }

S
Shuduo Sang 已提交
2957
    uint64_t  currentPrintTime = taosGetTimestampMs();
2958
    if (currentPrintTime - lastPrintTime > 30*1000) {
2959
      printf("thread[%d] already create %"PRIu64" - %"PRIu64" tables\n",
2960
              pThreadInfo->threadID, pThreadInfo->start_table_from, i);
2961 2962 2963
      lastPrintTime = currentPrintTime;
    }
  }
2964

2965
  if (0 != len) {
2966
    if (0 != queryDbExec(pThreadInfo->taos, buffer, NO_INSERT_TYPE, false)) {
2967
      errorPrint( "queryDbExec() failed. buffer:\n%s\n", buffer);
2968
    }
2969
  }
2970

2971 2972 2973 2974
  free(buffer);
  return NULL;
}

2975
static int startMultiThreadCreateChildTable(
2976
        char* cols, int threads, uint64_t tableFrom, int64_t ntables,
2977
        char* db_name, SSuperTable* superTblInfo) {
2978

2979
  pthread_t *pids = malloc(threads * sizeof(pthread_t));
2980
  threadInfo *infos = calloc(1, threads * sizeof(threadInfo));
2981 2982 2983 2984 2985 2986 2987 2988 2989 2990

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

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

S
Shuduo Sang 已提交
2991
  int64_t a = ntables / threads;
2992 2993 2994 2995 2996
  if (a < 1) {
    threads = ntables;
    a = 1;
  }

S
Shuduo Sang 已提交
2997
  int64_t b = 0;
2998
  b = ntables % threads;
2999

3000 3001 3002 3003 3004
  for (int64_t i = 0; i < threads; i++) {
    threadInfo *pThreadInfo = infos + i;
    pThreadInfo->threadID = i;
    tstrncpy(pThreadInfo->db_name, db_name, MAX_DB_NAME_SIZE);
    pThreadInfo->superTblInfo = superTblInfo;
3005
    verbosePrint("%s() %d db_name: %s\n", __func__, __LINE__, db_name);
3006
    pThreadInfo->taos = taos_connect(
3007 3008 3009 3010 3011
            g_Dbs.host,
            g_Dbs.user,
            g_Dbs.password,
            db_name,
            g_Dbs.port);
3012
    if (pThreadInfo->taos == NULL) {
3013
      errorPrint( "%s() LN%d, Failed to connect to TDengine, reason:%s\n",
3014
         __func__, __LINE__, taos_errstr(NULL));
3015
      free(pids);
3016
      free(infos);
3017 3018
      return -1;
    }
3019

3020
    pThreadInfo->start_table_from = tableFrom;
3021
    pThreadInfo->ntables = i<b?a+1:a;
3022 3023
    pThreadInfo->end_table_to = i < b ? tableFrom + a : tableFrom + a - 1;
    tableFrom = pThreadInfo->end_table_to + 1;
3024 3025 3026 3027
    pThreadInfo->use_metric = true;
    pThreadInfo->cols = cols;
    pThreadInfo->minDelay = UINT64_MAX;
    pthread_create(pids + i, NULL, createTable, pThreadInfo);
3028
  }
3029

3030 3031 3032 3033 3034
  for (int i = 0; i < threads; i++) {
    pthread_join(pids[i], NULL);
  }

  for (int i = 0; i < threads; i++) {
3035 3036
    threadInfo *pThreadInfo = infos + i;
    taos_close(pThreadInfo->taos);
3037 3038 3039
  }

  free(pids);
3040
  free(infos);
3041 3042

  return 0;
3043 3044
}

3045
static void createChildTables() {
3046 3047
    char tblColsBuf[MAX_SQL_SIZE];
    int len;
3048

3049
  for (int i = 0; i < g_Dbs.dbCount; i++) {
3050 3051
    if (g_Dbs.use_metric) {
      if (g_Dbs.db[i].superTblCount > 0) {
3052
          // with super table
S
Shuduo Sang 已提交
3053
        for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) {
3054
          if ((AUTO_CREATE_SUBTBL == g_Dbs.db[i].superTbls[j].autoCreateTable)
3055
                || (TBL_ALREADY_EXISTS == g_Dbs.db[i].superTbls[j].childTblExists)) {
3056 3057
            continue;
          }
3058

3059
          verbosePrint("%s() LN%d: %s\n", __func__, __LINE__,
3060
                  g_Dbs.db[i].superTbls[j].colsOfCreateChildTable);
3061
          uint64_t tableFrom = 0;
3062 3063
          g_totalChildTables += g_Dbs.db[i].superTbls[j].childTblCount;

3064
          verbosePrint("%s() LN%d: create %"PRId64" child tables from %"PRIu64"\n",
3065
                  __func__, __LINE__, g_totalChildTables, tableFrom);
3066
          startMultiThreadCreateChildTable(
3067 3068
                g_Dbs.db[i].superTbls[j].colsOfCreateChildTable,
                g_Dbs.threadCountByCreateTbl,
3069
                tableFrom,
3070 3071
                g_Dbs.db[i].superTbls[j].childTblCount,
                g_Dbs.db[i].dbName, &(g_Dbs.db[i].superTbls[j]));
3072
        }
3073 3074
      }
    } else {
3075 3076
      // normal table
      len = snprintf(tblColsBuf, MAX_SQL_SIZE, "(TS TIMESTAMP");
H
Haojun Liao 已提交
3077
      for (int j = 0; j < g_args.num_of_CPR; j++) {
3078 3079 3080 3081 3082 3083 3084 3085 3086 3087
          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,
                      ", COL%d %s(%d)", j, g_args.datatype[j], g_args.len_of_binary);
          } else {
              snprintf(tblColsBuf + len, MAX_SQL_SIZE - len,
                      ", COL%d %s", j, g_args.datatype[j]);
          }
          len = strlen(tblColsBuf);
3088
      }
3089

3090
      snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, ")");
3091

3092
      verbosePrint("%s() LN%d: dbName: %s num of tb: %"PRId64" schema: %s\n",
3093 3094
              __func__, __LINE__,
              g_Dbs.db[i].dbName, g_args.num_of_tables, tblColsBuf);
3095
      startMultiThreadCreateChildTable(
3096 3097 3098 3099 3100 3101
            tblColsBuf,
            g_Dbs.threadCountByCreateTbl,
            0,
            g_args.num_of_tables,
            g_Dbs.db[i].dbName,
            NULL);
3102
    }
3103 3104 3105 3106 3107 3108
  }
}

/*
  Read 10000 lines at most. If more than 10000 lines, continue to read after using
*/
3109
static int readTagFromCsvFileToMem(SSuperTable  * superTblInfo) {
3110 3111 3112
  size_t  n = 0;
  ssize_t readLen = 0;
  char *  line = NULL;
3113

3114 3115
  FILE *fp = fopen(superTblInfo->tagsFile, "r");
  if (fp == NULL) {
3116
    printf("Failed to open tags file: %s, reason:%s\n",
3117
            superTblInfo->tagsFile, strerror(errno));
3118 3119 3120 3121 3122 3123 3124
    return -1;
  }

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

3126 3127 3128 3129 3130 3131 3132 3133 3134
  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;
  }

3135
  while((readLen = tgetline(&line, &n, fp)) != -1) {
3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147
    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) {
3148
      char *tmp = realloc(tagDataBuf,
3149
              (size_t)tagCount*1.5*superTblInfo->lenOfTagOfOneRow);
3150 3151 3152
      if (tmp != NULL) {
        tagDataBuf = tmp;
        tagCount = (int)(tagCount*1.5);
3153
        memset(tagDataBuf + count*superTblInfo->lenOfTagOfOneRow,
3154
                0, (size_t)((tagCount-count)*superTblInfo->lenOfTagOfOneRow));
3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173
      } 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;
}

3174
#if 0
3175 3176 3177 3178
int readSampleFromJsonFileToMem(SSuperTable  * superTblInfo) {
  // TODO
  return 0;
}
3179
#endif
3180 3181 3182 3183

/*
  Read 10000 lines at most. If more than 10000 lines, continue to read after using
*/
3184
static int readSampleFromCsvFileToMem(
3185
        SSuperTable* superTblInfo) {
3186 3187 3188 3189
  size_t  n = 0;
  ssize_t readLen = 0;
  char *  line = NULL;
  int getRows = 0;
3190

3191 3192
  FILE*  fp = fopen(superTblInfo->sampleFile, "r");
  if (fp == NULL) {
3193 3194 3195
      errorPrint( "Failed to open sample file: %s, reason:%s\n",
              superTblInfo->sampleFile, strerror(errno));
      return -1;
3196
  }
3197

3198
  assert(superTblInfo->sampleDataBuf);
3199
  memset(superTblInfo->sampleDataBuf, 0,
3200
          MAX_SAMPLES_ONCE_FROM_FILE * superTblInfo->lenOfOneRow);
3201
  while(1) {
3202
    readLen = tgetline(&line, &n, fp);
3203 3204
    if (-1 == readLen) {
      if(0 != fseek(fp, 0, SEEK_SET)) {
3205
        errorPrint( "Failed to fseek file: %s, reason:%s\n",
3206
                superTblInfo->sampleFile, strerror(errno));
3207
        fclose(fp);
3208 3209 3210 3211
        return -1;
      }
      continue;
    }
3212

3213 3214 3215 3216 3217 3218 3219 3220 3221
    if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) {
      line[--readLen] = 0;
    }

    if (readLen == 0) {
      continue;
    }

    if (readLen > superTblInfo->lenOfOneRow) {
3222
      printf("sample row len[%d] overflow define schema len[%"PRIu64"], so discard this row\n",
3223
              (int32_t)readLen, superTblInfo->lenOfOneRow);
3224 3225 3226
      continue;
    }

3227
    memcpy(superTblInfo->sampleDataBuf + getRows * superTblInfo->lenOfOneRow,
3228
          line, readLen);
3229 3230 3231 3232 3233 3234 3235
    getRows++;

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

3236
  fclose(fp);
3237 3238 3239 3240
  tmfree(line);
  return 0;
}

3241
static bool getColumnAndTagTypeFromInsertJsonFile(
3242
        cJSON* stbInfo, SSuperTable* superTbls) {
3243
  bool  ret = false;
3244

3245
  // columns
3246 3247
  cJSON *columns = cJSON_GetObjectItem(stbInfo, "columns");
  if (columns && columns->type != cJSON_Array) {
3248
    printf("ERROR: failed to read json, columns not found\n");
3249 3250 3251 3252 3253 3254
    goto PARSE_OVER;
  } else if (NULL == columns) {
    superTbls->columnCount = 0;
    superTbls->tagCount    = 0;
    return true;
  }
3255

3256
  int columnSize = cJSON_GetArraySize(columns);
3257
  if ((columnSize + 1/* ts */) > MAX_COLUMN_COUNT) {
3258
    errorPrint("%s() LN%d, failed to read json, column size overflow, max column size is %d\n",
3259
            __func__, __LINE__, MAX_COLUMN_COUNT);
3260 3261 3262 3263 3264 3265
    goto PARSE_OVER;
  }

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

3267
  //superTbls->columnCount = columnSize;
3268 3269 3270 3271 3272 3273 3274
  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) {
3275
      count = countObj->valueint;
3276
    } else if (countObj && countObj->type != cJSON_Number) {
3277
      errorPrint("%s() LN%d, failed to read json, column count not found\n",
3278
          __func__, __LINE__);
3279 3280 3281 3282 3283
      goto PARSE_OVER;
    } else {
      count = 1;
    }

3284
    // column info
3285 3286
    memset(&columnCase, 0, sizeof(StrColumn));
    cJSON *dataType = cJSON_GetObjectItem(column, "type");
3287 3288 3289
    if (!dataType || dataType->type != cJSON_String
        || dataType->valuestring == NULL) {
      errorPrint("%s() LN%d: failed to read json, column type not found\n",
3290
          __func__, __LINE__);
3291 3292
      goto PARSE_OVER;
    }
3293 3294
    //tstrncpy(superTbls->columns[k].dataType, dataType->valuestring, MAX_TB_NAME_SIZE);
    tstrncpy(columnCase.dataType, dataType->valuestring, MAX_TB_NAME_SIZE);
3295

3296 3297
    cJSON* dataLen = cJSON_GetObjectItem(column, "len");
    if (dataLen && dataLen->type == cJSON_Number) {
3298
      columnCase.dataLen = dataLen->valueint;
3299
    } else if (dataLen && dataLen->type != cJSON_Number) {
3300
      debugPrint("%s() LN%d: failed to read json, column len not found\n",
3301
          __func__, __LINE__);
3302 3303 3304 3305
      goto PARSE_OVER;
    } else {
      columnCase.dataLen = 8;
    }
3306

3307
    for (int n = 0; n < count; ++n) {
3308
      tstrncpy(superTbls->columns[index].dataType,
3309
              columnCase.dataType, MAX_TB_NAME_SIZE);
3310
      superTbls->columns[index].dataLen = columnCase.dataLen;
3311 3312
      index++;
    }
3313
  }
3314

3315 3316
  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",
3317
            __func__, __LINE__, MAX_COLUMN_COUNT);
3318 3319 3320
    goto PARSE_OVER;
  }

3321
  superTbls->columnCount = index;
3322

3323 3324
  count = 1;
  index = 0;
3325
  // tags
3326 3327
  cJSON *tags = cJSON_GetObjectItem(stbInfo, "tags");
  if (!tags || tags->type != cJSON_Array) {
3328
    errorPrint("%s() LN%d, failed to read json, tags not found\n",
3329
        __func__, __LINE__);
3330 3331
    goto PARSE_OVER;
  }
3332

3333 3334
  int tagSize = cJSON_GetArraySize(tags);
  if (tagSize > MAX_TAG_COUNT) {
3335
    errorPrint("%s() LN%d, failed to read json, tags size overflow, max tag size is %d\n",
3336
        __func__, __LINE__, MAX_TAG_COUNT);
3337 3338
    goto PARSE_OVER;
  }
3339 3340

  //superTbls->tagCount = tagSize;
3341 3342 3343
  for (int k = 0; k < tagSize; ++k) {
    cJSON* tag = cJSON_GetArrayItem(tags, k);
    if (tag == NULL) continue;
3344

3345 3346 3347
    count = 1;
    cJSON* countObj = cJSON_GetObjectItem(tag, "count");
    if (countObj && countObj->type == cJSON_Number) {
3348
      count = countObj->valueint;
3349
    } else if (countObj && countObj->type != cJSON_Number) {
3350
      printf("ERROR: failed to read json, column count not found\n");
3351 3352 3353 3354 3355
      goto PARSE_OVER;
    } else {
      count = 1;
    }

3356
    // column info
3357 3358
    memset(&columnCase, 0, sizeof(StrColumn));
    cJSON *dataType = cJSON_GetObjectItem(tag, "type");
3359 3360 3361
    if (!dataType || dataType->type != cJSON_String
        || dataType->valuestring == NULL) {
      errorPrint("%s() LN%d, failed to read json, tag type not found\n",
3362
          __func__, __LINE__);
3363 3364
      goto PARSE_OVER;
    }
3365
    tstrncpy(columnCase.dataType, dataType->valuestring, MAX_TB_NAME_SIZE);
3366

3367 3368
    cJSON* dataLen = cJSON_GetObjectItem(tag, "len");
    if (dataLen && dataLen->type == cJSON_Number) {
3369
      columnCase.dataLen = dataLen->valueint;
3370
    } else if (dataLen && dataLen->type != cJSON_Number) {
3371
      errorPrint("%s() LN%d, failed to read json, column len not found\n",
3372
          __func__, __LINE__);
3373 3374 3375
      goto PARSE_OVER;
    } else {
      columnCase.dataLen = 0;
3376 3377
    }

3378
    for (int n = 0; n < count; ++n) {
3379
      tstrncpy(superTbls->tags[index].dataType, columnCase.dataType,
3380
          MAX_TB_NAME_SIZE);
3381
      superTbls->tags[index].dataLen = columnCase.dataLen;
3382 3383
      index++;
    }
3384
  }
3385 3386

  if (index > MAX_TAG_COUNT) {
3387
    errorPrint("%s() LN%d, failed to read json, tags size overflow, allowed max tag count is %d\n",
3388
        __func__, __LINE__, MAX_TAG_COUNT);
3389 3390 3391
    goto PARSE_OVER;
  }

3392 3393
  superTbls->tagCount = index;

3394 3395
  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",
3396
        __func__, __LINE__, MAX_COLUMN_COUNT);
3397 3398
    goto PARSE_OVER;
  }
3399 3400
  ret = true;

3401
PARSE_OVER:
3402 3403 3404 3405 3406 3407 3408 3409
  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) {
3410
    tstrncpy(g_Dbs.cfgDir, cfgdir->valuestring, MAX_FILE_NAME_LEN);
3411 3412 3413 3414
  }

  cJSON* host = cJSON_GetObjectItem(root, "host");
  if (host && host->type == cJSON_String && host->valuestring != NULL) {
3415
    tstrncpy(g_Dbs.host, host->valuestring, MAX_HOSTNAME_SIZE);
3416
  } else if (!host) {
3417
    tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
3418
  } else {
3419
    printf("ERROR: failed to read json, host not found\n");
3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431
    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) {
3432
    tstrncpy(g_Dbs.user, user->valuestring, MAX_USERNAME_SIZE);
3433
  } else if (!user) {
3434
    tstrncpy(g_Dbs.user, "root", MAX_USERNAME_SIZE);
3435 3436 3437 3438
  }

  cJSON* password = cJSON_GetObjectItem(root, "password");
  if (password && password->type == cJSON_String && password->valuestring != NULL) {
3439
    tstrncpy(g_Dbs.password, password->valuestring, MAX_PASSWORD_SIZE);
3440
  } else if (!password) {
3441
    tstrncpy(g_Dbs.password, "taosdata", MAX_PASSWORD_SIZE);
3442 3443 3444 3445
  }

  cJSON* resultfile = cJSON_GetObjectItem(root, "result_file");
  if (resultfile && resultfile->type == cJSON_String && resultfile->valuestring != NULL) {
3446
    tstrncpy(g_Dbs.resultFile, resultfile->valuestring, MAX_FILE_NAME_LEN);
3447
  } else if (!resultfile) {
3448
    tstrncpy(g_Dbs.resultFile, "./insert_res.txt", MAX_FILE_NAME_LEN);
3449 3450 3451 3452 3453 3454 3455 3456
  }

  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 {
3457
    printf("ERROR: failed to read json, threads not found\n");
3458
    goto PARSE_OVER;
3459 3460
  }

3461 3462 3463 3464
  cJSON* threads2 = cJSON_GetObjectItem(root, "thread_count_create_tbl");
  if (threads2 && threads2->type == cJSON_Number) {
    g_Dbs.threadCountByCreateTbl = threads2->valueint;
  } else if (!threads2) {
sangshuduo's avatar
sangshuduo 已提交
3465
    g_Dbs.threadCountByCreateTbl = 1;
3466
  } else {
3467
    errorPrint("%s() LN%d, failed to read json, threads2 not found\n",
3468
            __func__, __LINE__);
3469
    goto PARSE_OVER;
3470
  }
3471

3472 3473
  cJSON* gInsertInterval = cJSON_GetObjectItem(root, "insert_interval");
  if (gInsertInterval && gInsertInterval->type == cJSON_Number) {
3474 3475 3476 3477 3478
    if (gInsertInterval->valueint <0) {
      errorPrint("%s() LN%d, failed to read json, insert interval input mistake\n",
            __func__, __LINE__);
      goto PARSE_OVER;
    }
3479 3480 3481 3482
    g_args.insert_interval = gInsertInterval->valueint;
  } else if (!gInsertInterval) {
    g_args.insert_interval = 0;
  } else {
3483
    errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n",
3484
        __func__, __LINE__);
3485 3486
    goto PARSE_OVER;
  }
3487

3488 3489
  cJSON* interlaceRows = cJSON_GetObjectItem(root, "interlace_rows");
  if (interlaceRows && interlaceRows->type == cJSON_Number) {
3490 3491 3492 3493 3494 3495
    if (interlaceRows->valueint < 0) {
      errorPrint("%s() LN%d, failed to read json, interlace_rows input mistake\n",
        __func__, __LINE__);
      goto PARSE_OVER;

    }
3496 3497
    g_args.interlace_rows = interlaceRows->valueint;
  } else if (!interlaceRows) {
3498
    g_args.interlace_rows = 0; // 0 means progressive mode, > 0 mean interlace mode. max value is less or equ num_of_records_per_req
3499
  } else {
3500
    errorPrint("%s() LN%d, failed to read json, interlace_rows input mistake\n",
3501
        __func__, __LINE__);
3502
    goto PARSE_OVER;
3503
  }
3504

3505 3506
  cJSON* maxSqlLen = cJSON_GetObjectItem(root, "max_sql_len");
  if (maxSqlLen && maxSqlLen->type == cJSON_Number) {
3507 3508 3509 3510 3511
    if (maxSqlLen->valueint < 0) {
      errorPrint("%s() LN%d, failed to read json, max_sql_len input mistake\n",
        __func__, __LINE__);
      goto PARSE_OVER;
    }
3512 3513
    g_args.max_sql_len = maxSqlLen->valueint;
  } else if (!maxSqlLen) {
sangshuduo's avatar
sangshuduo 已提交
3514
    g_args.max_sql_len = (1024*1024);
3515
  } else {
3516
    errorPrint("%s() LN%d, failed to read json, max_sql_len input mistake\n",
3517
        __func__, __LINE__);
3518 3519 3520 3521 3522
    goto PARSE_OVER;
  }

  cJSON* numRecPerReq = cJSON_GetObjectItem(root, "num_of_records_per_req");
  if (numRecPerReq && numRecPerReq->type == cJSON_Number) {
3523
    if (numRecPerReq->valueint <= 0) {
3524 3525 3526
      errorPrint("%s() LN%d, failed to read json, num_of_records_per_req input mistake\n",
        __func__, __LINE__);
      goto PARSE_OVER;
3527
    } else if (numRecPerReq->valueint > MAX_RECORDS_PER_REQ) {
3528 3529 3530 3531 3532
      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();
3533
      numRecPerReq->valueint = MAX_RECORDS_PER_REQ;
3534
    }
3535 3536
    g_args.num_of_RPR = numRecPerReq->valueint;
  } else if (!numRecPerReq) {
3537
    g_args.num_of_RPR = MAX_RECORDS_PER_REQ;
3538
  } else {
3539
    errorPrint("%s() LN%d, failed to read json, num_of_records_per_req not found\n",
3540
        __func__, __LINE__);
3541 3542 3543
    goto PARSE_OVER;
  }

3544
  cJSON *answerPrompt = cJSON_GetObjectItem(root, "confirm_parameter_prompt"); // yes, no,
3545
  if (answerPrompt
3546 3547
          && answerPrompt->type == cJSON_String
          && answerPrompt->valuestring != NULL) {
3548 3549 3550 3551 3552 3553 3554 3555
    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) {
3556
    g_args.answer_yes = true;   // default is no, mean answer_yes.
3557
  } else {
3558
    errorPrint("%s", "failed to read json, confirm_parameter_prompt input mistake\n");
3559
    goto PARSE_OVER;
3560
  }
3561

3562 3563
  // rows per table need be less than insert batch
  if (g_args.interlace_rows > g_args.num_of_RPR) {
3564
      printf("NOTICE: interlace rows value %ud > num_of_records_per_req %ud\n\n",
3565
              g_args.interlace_rows, g_args.num_of_RPR);
3566
      printf("        interlace rows value will be set to num_of_records_per_req %ud\n\n",
3567 3568 3569 3570 3571
              g_args.num_of_RPR);
      prompt();
      g_args.interlace_rows = g_args.num_of_RPR;
  }

3572 3573
  cJSON* dbs = cJSON_GetObjectItem(root, "databases");
  if (!dbs || dbs->type != cJSON_Array) {
3574
    printf("ERROR: failed to read json, databases not found\n");
3575 3576 3577 3578 3579
    goto PARSE_OVER;
  }

  int dbSize = cJSON_GetArraySize(dbs);
  if (dbSize > MAX_DB_COUNT) {
3580
    errorPrint(
3581 3582
            "ERROR: failed to read json, databases size overflow, max database is %d\n",
            MAX_DB_COUNT);
3583 3584 3585 3586 3587 3588 3589 3590
    goto PARSE_OVER;
  }

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

3591
    // dbinfo
3592 3593
    cJSON *dbinfo = cJSON_GetObjectItem(dbinfos, "dbinfo");
    if (!dbinfo || dbinfo->type != cJSON_Object) {
3594
      printf("ERROR: failed to read json, dbinfo not found\n");
3595 3596
      goto PARSE_OVER;
    }
3597

3598 3599
    cJSON *dbName = cJSON_GetObjectItem(dbinfo, "name");
    if (!dbName || dbName->type != cJSON_String || dbName->valuestring == NULL) {
3600
      printf("ERROR: failed to read json, db name not found\n");
3601 3602
      goto PARSE_OVER;
    }
3603
    tstrncpy(g_Dbs.db[i].dbName, dbName->valuestring, MAX_DB_NAME_SIZE);
3604 3605 3606

    cJSON *drop = cJSON_GetObjectItem(dbinfo, "drop");
    if (drop && drop->type == cJSON_String && drop->valuestring != NULL) {
3607 3608
      if (0 == strncasecmp(drop->valuestring, "yes", strlen("yes"))) {
        g_Dbs.db[i].drop = true;
3609
      } else {
3610
        g_Dbs.db[i].drop = false;
3611
      }
3612
    } else if (!drop) {
3613
      g_Dbs.db[i].drop = g_args.drop_database;
3614
    } else {
3615
      errorPrint("%s() LN%d, failed to read json, drop input mistake\n",
3616
              __func__, __LINE__);
3617 3618 3619 3620
      goto PARSE_OVER;
    }

    cJSON *precision = cJSON_GetObjectItem(dbinfo, "precision");
3621
    if (precision && precision->type == cJSON_String
3622
            && precision->valuestring != NULL) {
3623
      tstrncpy(g_Dbs.db[i].dbCfg.precision, precision->valuestring,
3624
              MAX_DB_NAME_SIZE);
3625
    } else if (!precision) {
3626
      //tstrncpy(g_Dbs.db[i].dbCfg.precision, "ms", MAX_DB_NAME_SIZE);
3627 3628
      memset(g_Dbs.db[i].dbCfg.precision, 0, MAX_DB_NAME_SIZE);
    } else {
3629
      printf("ERROR: failed to read json, precision not found\n");
3630 3631 3632 3633 3634 3635 3636 3637 3638
      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 {
3639
      printf("ERROR: failed to read json, update not found\n");
3640 3641 3642 3643 3644 3645 3646 3647 3648
      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 {
3649
      printf("ERROR: failed to read json, replica not found\n");
3650 3651 3652 3653 3654 3655 3656 3657 3658
      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 {
3659 3660
     printf("ERROR: failed to read json, keep not found\n");
     goto PARSE_OVER;
3661
    }
3662

3663 3664 3665 3666 3667 3668
    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 {
3669 3670
     printf("ERROR: failed to read json, days not found\n");
     goto PARSE_OVER;
3671
    }
3672

3673 3674 3675 3676 3677 3678
    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 {
3679 3680
     printf("ERROR: failed to read json, cache not found\n");
     goto PARSE_OVER;
3681
    }
3682

3683 3684 3685 3686 3687 3688
    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 {
3689 3690
     printf("ERROR: failed to read json, block not found\n");
     goto PARSE_OVER;
3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706
    }

    //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) {
3707
      g_Dbs.db[i].dbCfg.minRows = 0;    // 0 means default
3708
    } else {
3709 3710
     printf("ERROR: failed to read json, minRows not found\n");
     goto PARSE_OVER;
3711 3712 3713 3714 3715 3716
    }

    cJSON* maxRows= cJSON_GetObjectItem(dbinfo, "maxRows");
    if (maxRows && maxRows->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.maxRows = maxRows->valueint;
    } else if (!maxRows) {
3717
      g_Dbs.db[i].dbCfg.maxRows = 0;    // 0 means default
3718
    } else {
3719 3720
     printf("ERROR: failed to read json, maxRows not found\n");
     goto PARSE_OVER;
3721 3722 3723 3724 3725 3726 3727 3728
    }

    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 {
3729 3730
     printf("ERROR: failed to read json, comp not found\n");
     goto PARSE_OVER;
3731 3732 3733 3734 3735 3736 3737 3738
    }

    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 {
3739 3740
     printf("ERROR: failed to read json, walLevel not found\n");
     goto PARSE_OVER;
3741 3742
    }

3743 3744 3745 3746 3747 3748
    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 {
3749 3750
     printf("ERROR: failed to read json, cacheLast not found\n");
     goto PARSE_OVER;
3751 3752
    }

3753 3754 3755 3756
    cJSON* quorum= cJSON_GetObjectItem(dbinfo, "quorum");
    if (quorum && quorum->type == cJSON_Number) {
      g_Dbs.db[i].dbCfg.quorum = quorum->valueint;
    } else if (!quorum) {
3757
      g_Dbs.db[i].dbCfg.quorum = 1;
3758
    } else {
3759 3760
     printf("failed to read json, quorum input mistake");
     goto PARSE_OVER;
3761 3762 3763 3764 3765 3766 3767 3768
    }

    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 {
3769
      errorPrint("%s() LN%d, failed to read json, fsync input mistake\n",
3770
              __func__, __LINE__);
3771
      goto PARSE_OVER;
3772
    }
3773

3774
    // super_talbes
3775 3776
    cJSON *stables = cJSON_GetObjectItem(dbinfos, "super_tables");
    if (!stables || stables->type != cJSON_Array) {
3777
      errorPrint("%s() LN%d, failed to read json, super_tables not found\n",
3778
              __func__, __LINE__);
3779
      goto PARSE_OVER;
3780 3781
    }

3782 3783
    int stbSize = cJSON_GetArraySize(stables);
    if (stbSize > MAX_SUPER_TABLE_COUNT) {
3784
      errorPrint(
3785 3786
              "%s() LN%d, failed to read json, supertable size overflow, max supertable is %d\n",
              __func__, __LINE__, MAX_SUPER_TABLE_COUNT);
3787 3788 3789 3790 3791 3792 3793
      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;
3794 3795

      // dbinfo
3796 3797
      cJSON *stbName = cJSON_GetObjectItem(stbInfo, "name");
      if (!stbName || stbName->type != cJSON_String || stbName->valuestring == NULL) {
3798
        errorPrint("%s() LN%d, failed to read json, stb name not found\n",
3799
                __func__, __LINE__);
3800 3801
        goto PARSE_OVER;
      }
3802
      tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring, MAX_TB_NAME_SIZE);
3803

3804 3805
      cJSON *prefix = cJSON_GetObjectItem(stbInfo, "childtable_prefix");
      if (!prefix || prefix->type != cJSON_String || prefix->valuestring == NULL) {
3806
        printf("ERROR: failed to read json, childtable_prefix not found\n");
3807 3808
        goto PARSE_OVER;
      }
3809
      tstrncpy(g_Dbs.db[i].superTbls[j].childTblPrefix, prefix->valuestring, MAX_DB_NAME_SIZE);
3810 3811

      cJSON *autoCreateTbl = cJSON_GetObjectItem(stbInfo, "auto_create_table"); // yes, no, null
3812
      if (autoCreateTbl
3813 3814
              && autoCreateTbl->type == cJSON_String
              && autoCreateTbl->valuestring != NULL) {
3815 3816 3817 3818 3819 3820 3821 3822 3823 3824
        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 {
3825
        printf("ERROR: failed to read json, auto_create_table not found\n");
3826 3827
        goto PARSE_OVER;
      }
3828

3829 3830 3831 3832
      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) {
3833
        g_Dbs.db[i].superTbls[j].batchCreateTableNum = 1000;
3834
      } else {
3835
        printf("ERROR: failed to read json, batch_create_tbl_num not found\n");
3836
        goto PARSE_OVER;
3837
      }
3838 3839

      cJSON *childTblExists = cJSON_GetObjectItem(stbInfo, "child_table_exists"); // yes, no
3840
      if (childTblExists
3841 3842
              && childTblExists->type == cJSON_String
              && childTblExists->valuestring != NULL) {
3843 3844
        if ((0 == strncasecmp(childTblExists->valuestring, "yes", 3))
            && (g_Dbs.db[i].drop == false)) {
3845
          g_Dbs.db[i].superTbls[j].childTblExists = TBL_ALREADY_EXISTS;
3846
        } else if ((0 == strncasecmp(childTblExists->valuestring, "no", 2)
3847
              || (g_Dbs.db[i].drop == true))) {
3848 3849 3850 3851 3852 3853 3854
          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 {
3855
        errorPrint("%s() LN%d, failed to read json, child_table_exists not found\n",
3856
                __func__, __LINE__);
3857 3858
        goto PARSE_OVER;
      }
3859

3860 3861
      cJSON* count = cJSON_GetObjectItem(stbInfo, "childtable_count");
      if (!count || count->type != cJSON_Number || 0 >= count->valueint) {
3862
        errorPrint("%s() LN%d, failed to read json, childtable_count input mistake\n",
3863
                __func__, __LINE__);
3864 3865 3866 3867 3868
        goto PARSE_OVER;
      }
      g_Dbs.db[i].superTbls[j].childTblCount = count->valueint;

      cJSON *dataSource = cJSON_GetObjectItem(stbInfo, "data_source");
3869
      if (dataSource && dataSource->type == cJSON_String
3870
              && dataSource->valuestring != NULL) {
3871
        tstrncpy(g_Dbs.db[i].superTbls[j].dataSource,
3872
                dataSource->valuestring, MAX_DB_NAME_SIZE);
3873
      } else if (!dataSource) {
3874
        tstrncpy(g_Dbs.db[i].superTbls[j].dataSource, "rand", MAX_DB_NAME_SIZE);
3875
      } else {
3876
        errorPrint("%s() LN%d, failed to read json, data_source not found\n",
3877
            __func__, __LINE__);
3878 3879 3880
        goto PARSE_OVER;
      }

3881 3882 3883 3884 3885 3886 3887 3888 3889
      cJSON *stbIface = cJSON_GetObjectItem(stbInfo, "insert_mode"); // taosc , rest, stmt
      if (stbIface && stbIface->type == cJSON_String
              && stbIface->valuestring != NULL) {
        if (0 == strcasecmp(stbIface->valuestring, "taosc")) {
            g_Dbs.db[i].superTbls[j].iface= TAOSC_IFACE;
        } else if (0 == strcasecmp(stbIface->valuestring, "rest")) {
            g_Dbs.db[i].superTbls[j].iface= REST_IFACE;
        } else if (0 == strcasecmp(stbIface->valuestring, "stmt")) {
            g_Dbs.db[i].superTbls[j].iface= STMT_IFACE;
3890 3891
        } else {
            errorPrint("%s() LN%d, failed to read json, insert_mode %s not recognized\n",
3892
                    __func__, __LINE__, stbIface->valuestring);
3893 3894
            goto PARSE_OVER;
        }
3895 3896
      } else if (!stbIface) {
        g_Dbs.db[i].superTbls[j].iface = TAOSC_IFACE;
3897
      } else {
3898
        errorPrint("%s", "failed to read json, insert_mode not found\n");
3899 3900 3901
        goto PARSE_OVER;
      }

3902
      cJSON* childTbl_limit = cJSON_GetObjectItem(stbInfo, "childtable_limit");
3903 3904
      if ((childTbl_limit) && (g_Dbs.db[i].drop != true)
          && (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) {
3905
        if (childTbl_limit->type != cJSON_Number) {
3906 3907
            printf("ERROR: failed to read json, childtable_limit\n");
            goto PARSE_OVER;
3908 3909 3910
        }
        g_Dbs.db[i].superTbls[j].childTblLimit = childTbl_limit->valueint;
      } else {
3911
        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.
3912 3913 3914
      }

      cJSON* childTbl_offset = cJSON_GetObjectItem(stbInfo, "childtable_offset");
3915 3916
      if ((childTbl_offset) && (g_Dbs.db[i].drop != true)
          && (g_Dbs.db[i].superTbls[j].childTblExists == TBL_ALREADY_EXISTS)) {
3917
        if (childTbl_offset->type != cJSON_Number || 0 > childTbl_offset->valueint) {
3918 3919
            printf("ERROR: failed to read json, childtable_offset\n");
            goto PARSE_OVER;
3920 3921 3922 3923 3924 3925
        }
        g_Dbs.db[i].superTbls[j].childTblOffset = childTbl_offset->valueint;
      } else {
        g_Dbs.db[i].superTbls[j].childTblOffset = 0;
      }

3926 3927
      cJSON *ts = cJSON_GetObjectItem(stbInfo, "start_timestamp");
      if (ts && ts->type == cJSON_String && ts->valuestring != NULL) {
3928
        tstrncpy(g_Dbs.db[i].superTbls[j].startTimestamp,
3929
                ts->valuestring, MAX_DB_NAME_SIZE);
3930
      } else if (!ts) {
3931
        tstrncpy(g_Dbs.db[i].superTbls[j].startTimestamp,
3932
                "now", MAX_DB_NAME_SIZE);
3933
      } else {
3934
        printf("ERROR: failed to read json, start_timestamp not found\n");
3935 3936
        goto PARSE_OVER;
      }
3937

3938 3939 3940 3941
      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) {
3942
        g_Dbs.db[i].superTbls[j].timeStampStep = DEFAULT_TIMESTAMP_STEP;
3943
      } else {
3944
        printf("ERROR: failed to read json, timestamp_step not found\n");
3945 3946 3947 3948
        goto PARSE_OVER;
      }

      cJSON *sampleFormat = cJSON_GetObjectItem(stbInfo, "sample_format");
3949
      if (sampleFormat && sampleFormat->type
3950
              == cJSON_String && sampleFormat->valuestring != NULL) {
3951
        tstrncpy(g_Dbs.db[i].superTbls[j].sampleFormat,
3952
                sampleFormat->valuestring, MAX_DB_NAME_SIZE);
3953
      } else if (!sampleFormat) {
3954
        tstrncpy(g_Dbs.db[i].superTbls[j].sampleFormat, "csv", MAX_DB_NAME_SIZE);
3955
      } else {
3956
        printf("ERROR: failed to read json, sample_format not found\n");
3957
        goto PARSE_OVER;
3958
      }
3959

3960
      cJSON *sampleFile = cJSON_GetObjectItem(stbInfo, "sample_file");
3961 3962
      if (sampleFile && sampleFile->type == cJSON_String
          && sampleFile->valuestring != NULL) {
3963
        tstrncpy(g_Dbs.db[i].superTbls[j].sampleFile,
3964
                sampleFile->valuestring, MAX_FILE_NAME_LEN);
3965 3966 3967
      } else if (!sampleFile) {
        memset(g_Dbs.db[i].superTbls[j].sampleFile, 0, MAX_FILE_NAME_LEN);
      } else {
3968
        printf("ERROR: failed to read json, sample_file not found\n");
3969
        goto PARSE_OVER;
3970
      }
3971

3972 3973
      cJSON *tagsFile = cJSON_GetObjectItem(stbInfo, "tags_file");
      if (tagsFile && tagsFile->type == cJSON_String && tagsFile->valuestring != NULL) {
3974
        tstrncpy(g_Dbs.db[i].superTbls[j].tagsFile,
3975
                tagsFile->valuestring, MAX_FILE_NAME_LEN);
3976 3977 3978 3979 3980 3981 3982 3983 3984
        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 {
3985
        printf("ERROR: failed to read json, tags_file not found\n");
3986 3987
        goto PARSE_OVER;
      }
3988

sangshuduo's avatar
sangshuduo 已提交
3989 3990 3991
      cJSON* stbMaxSqlLen = cJSON_GetObjectItem(stbInfo, "max_sql_len");
      if (stbMaxSqlLen && stbMaxSqlLen->type == cJSON_Number) {
        int32_t len = stbMaxSqlLen->valueint;
3992 3993
        if (len > TSDB_MAX_ALLOWED_SQL_LEN) {
          len = TSDB_MAX_ALLOWED_SQL_LEN;
3994 3995
        } else if (len < 5) {
          len = 5;
3996
        }
3997 3998
        g_Dbs.db[i].superTbls[j].maxSqlLen = len;
      } else if (!maxSqlLen) {
3999
        g_Dbs.db[i].superTbls[j].maxSqlLen = g_args.max_sql_len;
4000
      } else {
sangshuduo's avatar
sangshuduo 已提交
4001
        errorPrint("%s() LN%d, failed to read json, stbMaxSqlLen input mistake\n",
4002
            __func__, __LINE__);
4003
        goto PARSE_OVER;
4004
      }
4005
/*
4006 4007 4008 4009 4010
      cJSON *multiThreadWriteOneTbl =
          cJSON_GetObjectItem(stbInfo, "multi_thread_write_one_tbl"); // no , yes
      if (multiThreadWriteOneTbl
              && multiThreadWriteOneTbl->type == cJSON_String
              && multiThreadWriteOneTbl->valuestring != NULL) {
4011 4012 4013 4014
        if (0 == strncasecmp(multiThreadWriteOneTbl->valuestring, "yes", 3)) {
          g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl = 1;
        } else {
          g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl = 0;
4015
        }
4016 4017 4018
      } else if (!multiThreadWriteOneTbl) {
        g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl = 0;
      } else {
4019
        printf("ERROR: failed to read json, multiThreadWriteOneTbl not found\n");
4020 4021
        goto PARSE_OVER;
      }
4022
*/
sangshuduo's avatar
sangshuduo 已提交
4023 4024 4025
      cJSON* stbInterlaceRows = cJSON_GetObjectItem(stbInfo, "interlace_rows");
      if (stbInterlaceRows && stbInterlaceRows->type == cJSON_Number) {
        if (stbInterlaceRows->valueint < 0) {
4026 4027 4028 4029
          errorPrint("%s() LN%d, failed to read json, interlace rows input mistake\n",
            __func__, __LINE__);
          goto PARSE_OVER;
        }
sangshuduo's avatar
sangshuduo 已提交
4030
        g_Dbs.db[i].superTbls[j].interlaceRows = stbInterlaceRows->valueint;
4031 4032
        // rows per table need be less than insert batch
        if (g_Dbs.db[i].superTbls[j].interlaceRows > g_args.num_of_RPR) {
4033 4034 4035 4036
          printf("NOTICE: db[%d].superTbl[%d]'s interlace rows value %ud > num_of_records_per_req %ud\n\n",
                  i, j, g_Dbs.db[i].superTbls[j].interlaceRows,
                  g_args.num_of_RPR);
          printf("        interlace rows value will be set to num_of_records_per_req %ud\n\n",
4037
                  g_args.num_of_RPR);
4038
          prompt();
4039 4040
          g_Dbs.db[i].superTbls[j].interlaceRows = g_args.num_of_RPR;
        }
sangshuduo's avatar
sangshuduo 已提交
4041
      } else if (!stbInterlaceRows) {
4042
        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
4043
      } else {
4044
        errorPrint(
4045 4046
                "%s() LN%d, failed to read json, interlace rows input mistake\n",
                __func__, __LINE__);
4047
        goto PARSE_OVER;
4048
      }
4049 4050 4051

      cJSON* disorderRatio = cJSON_GetObjectItem(stbInfo, "disorder_ratio");
      if (disorderRatio && disorderRatio->type == cJSON_Number) {
4052 4053 4054 4055 4056 4057
        if (disorderRatio->valueint > 50)
          disorderRatio->valueint = 50;

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

4058 4059 4060 4061
        g_Dbs.db[i].superTbls[j].disorderRatio = disorderRatio->valueint;
      } else if (!disorderRatio) {
        g_Dbs.db[i].superTbls[j].disorderRatio = 0;
      } else {
4062
        printf("ERROR: failed to read json, disorderRatio not found\n");
4063
        goto PARSE_OVER;
4064
      }
4065 4066 4067 4068 4069 4070 4071

      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 {
4072
        printf("ERROR: failed to read json, disorderRange not found\n");
4073 4074
        goto PARSE_OVER;
      }
4075

4076 4077
      cJSON* insertRows = cJSON_GetObjectItem(stbInfo, "insert_rows");
      if (insertRows && insertRows->type == cJSON_Number) {
4078 4079 4080 4081 4082
        if (insertRows->valueint < 0) {
          errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
                __func__, __LINE__);
          goto PARSE_OVER;
        }
4083 4084 4085 4086
        g_Dbs.db[i].superTbls[j].insertRows = insertRows->valueint;
      } else if (!insertRows) {
        g_Dbs.db[i].superTbls[j].insertRows = 0x7FFFFFFFFFFFFFFF;
      } else {
4087
        errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n",
4088
                __func__, __LINE__);
4089 4090 4091 4092 4093 4094
        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;
4095 4096 4097 4098 4099
        if (insertInterval->valueint < 0) {
          errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n",
                __func__, __LINE__);
          goto PARSE_OVER;
        }
4100
      } else if (!insertInterval) {
4101
        verbosePrint("%s() LN%d: stable insert interval be overrided by global %"PRIu64".\n",
4102
                __func__, __LINE__, g_args.insert_interval);
4103 4104
        g_Dbs.db[i].superTbls[j].insertInterval = g_args.insert_interval;
      } else {
4105
        errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n",
4106
                __func__, __LINE__);
4107 4108 4109
        goto PARSE_OVER;
      }

4110
      int retVal = getColumnAndTagTypeFromInsertJsonFile(
4111
              stbInfo, &g_Dbs.db[i].superTbls[j]);
4112 4113
      if (false == retVal) {
        goto PARSE_OVER;
4114 4115
      }
    }
4116 4117 4118 4119
  }

  ret = true;

4120
PARSE_OVER:
4121 4122 4123 4124 4125 4126 4127 4128
  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) {
4129
    tstrncpy(g_queryInfo.cfgDir, cfgdir->valuestring, MAX_FILE_NAME_LEN);
4130 4131 4132 4133
  }

  cJSON* host = cJSON_GetObjectItem(root, "host");
  if (host && host->type == cJSON_String && host->valuestring != NULL) {
4134
    tstrncpy(g_queryInfo.host, host->valuestring, MAX_HOSTNAME_SIZE);
4135
  } else if (!host) {
4136
    tstrncpy(g_queryInfo.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
4137
  } else {
4138
    printf("ERROR: failed to read json, host not found\n");
4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150
    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) {
4151
    tstrncpy(g_queryInfo.user, user->valuestring, MAX_USERNAME_SIZE);
4152
  } else if (!user) {
4153
    tstrncpy(g_queryInfo.user, "root", MAX_USERNAME_SIZE); ;
4154 4155 4156 4157
  }

  cJSON* password = cJSON_GetObjectItem(root, "password");
  if (password && password->type == cJSON_String && password->valuestring != NULL) {
4158
    tstrncpy(g_queryInfo.password, password->valuestring, MAX_PASSWORD_SIZE);
4159
  } else if (!password) {
4160
    tstrncpy(g_queryInfo.password, "taosdata", MAX_PASSWORD_SIZE);;
4161
  }
H
hzcheng 已提交
4162

4163
  cJSON *answerPrompt = cJSON_GetObjectItem(root, "confirm_parameter_prompt"); // yes, no,
4164
  if (answerPrompt && answerPrompt->type == cJSON_String
4165
          && answerPrompt->valuestring != NULL) {
4166 4167 4168 4169
    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 已提交
4170
    } else {
4171
      g_args.answer_yes = false;
H
hzcheng 已提交
4172
    }
4173 4174 4175
  } else if (!answerPrompt) {
    g_args.answer_yes = false;
  } else {
4176
    printf("ERROR: failed to read json, confirm_parameter_prompt not found\n");
4177
    goto PARSE_OVER;
4178
  }
4179

4180 4181
  cJSON* gQueryTimes = cJSON_GetObjectItem(root, "query_times");
  if (gQueryTimes && gQueryTimes->type == cJSON_Number) {
4182
    if (gQueryTimes->valueint <= 0) {
4183 4184
      errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
        __func__, __LINE__);
4185 4186
      goto PARSE_OVER;
    }
4187 4188 4189 4190
    g_args.query_times = gQueryTimes->valueint;
  } else if (!gQueryTimes) {
    g_args.query_times = 1;
  } else {
4191
    errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
4192
        __func__, __LINE__);
4193 4194 4195
    goto PARSE_OVER;
  }

4196 4197
  cJSON* dbs = cJSON_GetObjectItem(root, "databases");
  if (dbs && dbs->type == cJSON_String && dbs->valuestring != NULL) {
4198
    tstrncpy(g_queryInfo.dbName, dbs->valuestring, MAX_DB_NAME_SIZE);
4199
  } else if (!dbs) {
4200
    printf("ERROR: failed to read json, databases not found\n");
4201
    goto PARSE_OVER;
H
hzcheng 已提交
4202
  }
4203 4204 4205

  cJSON* queryMode = cJSON_GetObjectItem(root, "query_mode");
  if (queryMode && queryMode->type == cJSON_String && queryMode->valuestring != NULL) {
4206
    tstrncpy(g_queryInfo.queryMode, queryMode->valuestring, MAX_TB_NAME_SIZE);
4207
  } else if (!queryMode) {
4208
    tstrncpy(g_queryInfo.queryMode, "taosc", MAX_TB_NAME_SIZE);
4209
  } else {
4210
    printf("ERROR: failed to read json, query_mode not found\n");
4211
    goto PARSE_OVER;
H
hzcheng 已提交
4212
  }
4213

4214
  // specified_table_query
4215 4216
  cJSON *specifiedQuery = cJSON_GetObjectItem(root, "specified_table_query");
  if (!specifiedQuery) {
4217
    g_queryInfo.specifiedQueryInfo.concurrent = 1;
4218 4219
    g_queryInfo.specifiedQueryInfo.sqlCount = 0;
  } else if (specifiedQuery->type != cJSON_Object) {
4220
    printf("ERROR: failed to read json, super_table_query not found\n");
4221
    goto PARSE_OVER;
4222
  } else {
4223 4224 4225 4226 4227
    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;
4228 4229
    }

4230
    cJSON* specifiedQueryTimes = cJSON_GetObjectItem(specifiedQuery,
4231
        "query_times");
4232
    if (specifiedQueryTimes && specifiedQueryTimes->type == cJSON_Number) {
4233
      if (specifiedQueryTimes->valueint <= 0) {
4234 4235
        errorPrint(
                "%s() LN%d, failed to read json, query_times: %"PRId64", need be a valid (>0) number\n",
4236
          __func__, __LINE__, specifiedQueryTimes->valueint);
4237 4238 4239
        goto PARSE_OVER;

      }
4240 4241 4242 4243
      g_queryInfo.specifiedQueryInfo.queryTimes = specifiedQueryTimes->valueint;
    } else if (!specifiedQueryTimes) {
      g_queryInfo.specifiedQueryInfo.queryTimes = g_args.query_times;
    } else {
4244
      errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
4245
          __func__, __LINE__);
4246
      goto PARSE_OVER;
4247
    }
4248

4249
    cJSON* concurrent = cJSON_GetObjectItem(specifiedQuery, "concurrent");
4250
    if (concurrent && concurrent->type == cJSON_Number) {
4251
      if (concurrent->valueint <= 0) {
4252
        errorPrint(
4253
                "%s() LN%d, query sqlCount %"PRIu64" or concurrent %d is not correct.\n",
4254 4255
              __func__, __LINE__,
              g_queryInfo.specifiedQueryInfo.sqlCount,
4256
              g_queryInfo.specifiedQueryInfo.concurrent);
4257 4258
        goto PARSE_OVER;
      }
4259
      g_queryInfo.specifiedQueryInfo.concurrent = concurrent->valueint;
4260
    } else if (!concurrent) {
4261
      g_queryInfo.specifiedQueryInfo.concurrent = 1;
4262
    }
4263

4264 4265 4266 4267 4268 4269 4270
    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;
4271
      } else {
4272
        errorPrint("%s() LN%d, failed to read json, async mode input error\n",
4273
            __func__, __LINE__);
4274 4275 4276
        goto PARSE_OVER;
      }
    } else {
4277
      g_queryInfo.specifiedQueryInfo.asyncMode = SYNC_MODE;
4278
    }
4279

4280
    cJSON* interval = cJSON_GetObjectItem(specifiedQuery, "interval");
4281
    if (interval && interval->type == cJSON_Number) {
4282
      g_queryInfo.specifiedQueryInfo.subscribeInterval = interval->valueint;
4283
    } else if (!interval) {
4284 4285
      //printf("failed to read json, subscribe interval no found\n");
      //goto PARSE_OVER;
4286
      g_queryInfo.specifiedQueryInfo.subscribeInterval = 10000;
4287
    }
4288

4289
    cJSON* restart = cJSON_GetObjectItem(specifiedQuery, "restart");
4290
    if (restart && restart->type == cJSON_String && restart->valuestring != NULL) {
4291
      if (0 == strcmp("yes", restart->valuestring)) {
4292
        g_queryInfo.specifiedQueryInfo.subscribeRestart = true;
4293
      } else if (0 == strcmp("no", restart->valuestring)) {
4294
        g_queryInfo.specifiedQueryInfo.subscribeRestart = false;
4295
      } else {
4296
        printf("ERROR: failed to read json, subscribe restart error\n");
4297 4298 4299
        goto PARSE_OVER;
      }
    } else {
4300
      g_queryInfo.specifiedQueryInfo.subscribeRestart = true;
4301
    }
4302

4303
    cJSON* keepProgress = cJSON_GetObjectItem(specifiedQuery, "keepProgress");
4304
    if (keepProgress
4305 4306
            && keepProgress->type == cJSON_String
            && keepProgress->valuestring != NULL) {
4307
      if (0 == strcmp("yes", keepProgress->valuestring)) {
4308
        g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 1;
4309
      } else if (0 == strcmp("no", keepProgress->valuestring)) {
4310
        g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 0;
4311
      } else {
4312
        printf("ERROR: failed to read json, subscribe keepProgress error\n");
4313 4314 4315
        goto PARSE_OVER;
      }
    } else {
4316
      g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 0;
4317 4318
    }

4319
    // sqls
4320 4321
    cJSON* specifiedSqls = cJSON_GetObjectItem(specifiedQuery, "sqls");
    if (!specifiedSqls) {
4322
      g_queryInfo.specifiedQueryInfo.sqlCount = 0;
4323
    } else if (specifiedSqls->type != cJSON_Array) {
4324
      errorPrint("%s() LN%d, failed to read json, super sqls not found\n",
4325
          __func__, __LINE__);
4326
      goto PARSE_OVER;
4327
    } else {
4328 4329 4330 4331 4332 4333 4334 4335
      int superSqlSize = cJSON_GetArraySize(specifiedSqls);
      if (superSqlSize * g_queryInfo.specifiedQueryInfo.concurrent
              > MAX_QUERY_SQL_COUNT) {
        errorPrint("%s() LN%d, failed to read json, query sql(%d) * concurrent(%d) overflow, max is %d\n",
           __func__, __LINE__,
           superSqlSize,
           g_queryInfo.specifiedQueryInfo.concurrent,
           MAX_QUERY_SQL_COUNT);
4336 4337
        goto PARSE_OVER;
      }
4338

4339
      g_queryInfo.specifiedQueryInfo.sqlCount = superSqlSize;
4340
      for (int j = 0; j < superSqlSize; ++j) {
4341
        cJSON* sql = cJSON_GetArrayItem(specifiedSqls, j);
4342
        if (sql == NULL) continue;
4343

4344 4345
        cJSON *sqlStr = cJSON_GetObjectItem(sql, "sql");
        if (!sqlStr || sqlStr->type != cJSON_String || sqlStr->valuestring == NULL) {
4346
          printf("ERROR: failed to read json, sql not found\n");
4347 4348
          goto PARSE_OVER;
        }
4349 4350
        tstrncpy(g_queryInfo.specifiedQueryInfo.sql[j],
                sqlStr->valuestring, MAX_QUERY_SQL_LENGTH);
H
hzcheng 已提交
4351

4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363
        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;
        }

4364
        cJSON *result = cJSON_GetObjectItem(sql, "result");
4365 4366 4367 4368
        if ((NULL != result) && (result->type == cJSON_String)
                && (result->valuestring != NULL)) {
          tstrncpy(g_queryInfo.specifiedQueryInfo.result[j],
                  result->valuestring, MAX_FILE_NAME_LEN);
4369
        } else if (NULL == result) {
4370 4371
          memset(g_queryInfo.specifiedQueryInfo.result[j],
                  0, MAX_FILE_NAME_LEN);
4372
        } else {
4373
          printf("ERROR: failed to read json, super query result file not found\n");
4374
          goto PARSE_OVER;
4375
        }
4376 4377 4378
      }
    }
  }
4379

4380
  // super_table_query
4381 4382
  cJSON *superQuery = cJSON_GetObjectItem(root, "super_table_query");
  if (!superQuery) {
4383
    g_queryInfo.superQueryInfo.threadCnt = 1;
4384 4385
    g_queryInfo.superQueryInfo.sqlCount = 0;
  } else if (superQuery->type != cJSON_Object) {
4386
    printf("ERROR: failed to read json, sub_table_query not found\n");
4387 4388
    ret = true;
    goto PARSE_OVER;
H
hzcheng 已提交
4389
  } else {
4390
    cJSON* subrate = cJSON_GetObjectItem(superQuery, "query_interval");
4391
    if (subrate && subrate->type == cJSON_Number) {
4392
      g_queryInfo.superQueryInfo.queryInterval = subrate->valueint;
4393
    } else if (!subrate) {
4394
      g_queryInfo.superQueryInfo.queryInterval = 0;
4395 4396 4397 4398
    }

    cJSON* superQueryTimes = cJSON_GetObjectItem(superQuery, "query_times");
    if (superQueryTimes && superQueryTimes->type == cJSON_Number) {
4399 4400
      if (superQueryTimes->valueint <= 0) {
        errorPrint("%s() LN%d, failed to read json, query_times: %"PRId64", need be a valid (>0) number\n",
4401
          __func__, __LINE__, superQueryTimes->valueint);
4402 4403
        goto PARSE_OVER;
      }
4404 4405 4406 4407
      g_queryInfo.superQueryInfo.queryTimes = superQueryTimes->valueint;
    } else if (!superQueryTimes) {
      g_queryInfo.superQueryInfo.queryTimes = g_args.query_times;
    } else {
4408
      errorPrint("%s() LN%d, failed to read json, query_times input mistake\n",
4409
          __func__, __LINE__);
4410
      goto PARSE_OVER;
4411
    }
4412

4413
    cJSON* threads = cJSON_GetObjectItem(superQuery, "threads");
4414
    if (threads && threads->type == cJSON_Number) {
4415 4416 4417 4418 4419 4420
      if (threads->valueint <= 0) {
        errorPrint("%s() LN%d, failed to read json, threads input mistake\n",
          __func__, __LINE__);
        goto PARSE_OVER;

      }
4421
      g_queryInfo.superQueryInfo.threadCnt = threads->valueint;
4422
    } else if (!threads) {
4423
      g_queryInfo.superQueryInfo.threadCnt = 1;
4424
    }
4425

4426
    //cJSON* subTblCnt = cJSON_GetObjectItem(superQuery, "childtable_count");
4427
    //if (subTblCnt && subTblCnt->type == cJSON_Number) {
4428
    //  g_queryInfo.superQueryInfo.childTblCount = subTblCnt->valueint;
4429
    //} else if (!subTblCnt) {
4430
    //  g_queryInfo.superQueryInfo.childTblCount = 0;
4431
    //}
4432

4433
    cJSON* stblname = cJSON_GetObjectItem(superQuery, "stblname");
4434 4435 4436
    if (stblname && stblname->type == cJSON_String
        && stblname->valuestring != NULL) {
      tstrncpy(g_queryInfo.superQueryInfo.sTblName, stblname->valuestring,
4437
          MAX_TB_NAME_SIZE);
4438
    } else {
4439
      errorPrint("%s() LN%d, failed to read json, super table name input error\n",
4440
          __func__, __LINE__);
4441 4442
      goto PARSE_OVER;
    }
4443

4444 4445 4446 4447 4448 4449 4450
    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;
4451
      } else {
4452
        errorPrint("%s() LN%d, failed to read json, async mode input error\n",
4453
            __func__, __LINE__);
4454 4455 4456
        goto PARSE_OVER;
      }
    } else {
4457
      g_queryInfo.superQueryInfo.asyncMode = SYNC_MODE;
4458
    }
4459

4460 4461 4462 4463 4464 4465 4466 4467 4468
    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) {
4469 4470
      //printf("failed to read json, subscribe interval no found\n");
      //goto PARSE_OVER;
4471
      g_queryInfo.superQueryInfo.subscribeInterval = 10000;
4472
    }
4473

4474
    cJSON* subrestart = cJSON_GetObjectItem(superQuery, "restart");
4475 4476
    if (subrestart && subrestart->type == cJSON_String
        && subrestart->valuestring != NULL) {
4477
      if (0 == strcmp("yes", subrestart->valuestring)) {
4478
        g_queryInfo.superQueryInfo.subscribeRestart = true;
4479
      } else if (0 == strcmp("no", subrestart->valuestring)) {
4480
        g_queryInfo.superQueryInfo.subscribeRestart = false;
4481
      } else {
4482
        printf("ERROR: failed to read json, subscribe restart error\n");
4483 4484 4485
        goto PARSE_OVER;
      }
    } else {
4486
      g_queryInfo.superQueryInfo.subscribeRestart = true;
4487
    }
4488

4489 4490 4491 4492 4493
    cJSON* superkeepProgress = cJSON_GetObjectItem(superQuery, "keepProgress");
    if (superkeepProgress &&
            superkeepProgress->type == cJSON_String
            && superkeepProgress->valuestring != NULL) {
      if (0 == strcmp("yes", superkeepProgress->valuestring)) {
4494
        g_queryInfo.superQueryInfo.subscribeKeepProgress = 1;
4495
      } else if (0 == strcmp("no", superkeepProgress->valuestring)) {
4496
        g_queryInfo.superQueryInfo.subscribeKeepProgress = 0;
4497
      } else {
4498
        printf("ERROR: failed to read json, subscribe super table keepProgress error\n");
4499 4500 4501
        goto PARSE_OVER;
      }
    } else {
4502
      g_queryInfo.superQueryInfo.subscribeKeepProgress = 0;
4503
    }
4504

4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516
    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;
    }

4517 4518 4519
    // supert table sqls
    cJSON* superSqls = cJSON_GetObjectItem(superQuery, "sqls");
    if (!superSqls) {
4520
      g_queryInfo.superQueryInfo.sqlCount = 0;
4521
    } else if (superSqls->type != cJSON_Array) {
4522
      errorPrint("%s() LN%d: failed to read json, super sqls not found\n",
4523
          __func__, __LINE__);
4524
      goto PARSE_OVER;
4525
    } else {
4526
      int superSqlSize = cJSON_GetArraySize(superSqls);
4527
      if (superSqlSize > MAX_QUERY_SQL_COUNT) {
4528
        errorPrint("%s() LN%d, failed to read json, query sql size overflow, max is %d\n",
4529
           __func__, __LINE__, MAX_QUERY_SQL_COUNT);
4530 4531
        goto PARSE_OVER;
      }
4532

4533
      g_queryInfo.superQueryInfo.sqlCount = superSqlSize;
4534
      for (int j = 0; j < superSqlSize; ++j) {
4535
        cJSON* sql = cJSON_GetArrayItem(superSqls, j);
4536
        if (sql == NULL) continue;
4537

4538
        cJSON *sqlStr = cJSON_GetObjectItem(sql, "sql");
4539 4540 4541
        if (!sqlStr || sqlStr->type != cJSON_String
            || sqlStr->valuestring == NULL) {
          errorPrint("%s() LN%d, failed to read json, sql not found\n",
4542
              __func__, __LINE__);
4543 4544
          goto PARSE_OVER;
        }
4545
        tstrncpy(g_queryInfo.superQueryInfo.sql[j], sqlStr->valuestring,
4546
            MAX_QUERY_SQL_LENGTH);
4547 4548

        cJSON *result = cJSON_GetObjectItem(sql, "result");
4549 4550 4551
        if (result != NULL && result->type == cJSON_String
            && result->valuestring != NULL){
          tstrncpy(g_queryInfo.superQueryInfo.result[j],
4552
              result->valuestring, MAX_FILE_NAME_LEN);
4553
        } else if (NULL == result) {
4554
          memset(g_queryInfo.superQueryInfo.result[j], 0, MAX_FILE_NAME_LEN);
4555
        }  else {
4556
          errorPrint("%s() LN%d, failed to read json, sub query result file not found\n",
4557
              __func__, __LINE__);
4558
          goto PARSE_OVER;
4559
        }
4560 4561
      }
    }
H
hzcheng 已提交
4562 4563
  }

4564
  ret = true;
H
hzcheng 已提交
4565

4566
PARSE_OVER:
4567 4568
  return ret;
}
H
hzcheng 已提交
4569

4570
static bool getInfoFromJsonFile(char* file) {
4571
    debugPrint("%s %d %s\n", __func__, __LINE__, file);
4572

4573 4574 4575 4576 4577
  FILE *fp = fopen(file, "r");
  if (!fp) {
    printf("failed to read %s, reason:%s\n", file, strerror(errno));
    return false;
  }
H
Hui Li 已提交
4578

4579
  bool  ret = false;
4580
  int   maxLen = 6400000;
4581 4582 4583 4584 4585 4586 4587
  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 已提交
4588
  }
H
Hui Li 已提交
4589

4590 4591 4592
  content[len] = 0;
  cJSON* root = cJSON_Parse(content);
  if (root == NULL) {
4593
    printf("ERROR: failed to cjson parse %s, invalid json format\n", file);
4594 4595
    goto PARSE_OVER;
  }
H
Hui Li 已提交
4596

4597 4598 4599
  cJSON* filetype = cJSON_GetObjectItem(root, "filetype");
  if (filetype && filetype->type == cJSON_String && filetype->valuestring != NULL) {
    if (0 == strcasecmp("insert", filetype->valuestring)) {
4600
      g_args.test_mode = INSERT_TEST;
4601
    } else if (0 == strcasecmp("query", filetype->valuestring)) {
4602
      g_args.test_mode = QUERY_TEST;
4603
    } else if (0 == strcasecmp("subscribe", filetype->valuestring)) {
4604
      g_args.test_mode = SUBSCRIBE_TEST;
4605
    } else {
4606
      printf("ERROR: failed to read json, filetype not support\n");
4607 4608 4609
      goto PARSE_OVER;
    }
  } else if (!filetype) {
4610
    g_args.test_mode = INSERT_TEST;
4611
  } else {
4612
    printf("ERROR: failed to read json, filetype not found\n");
4613 4614
    goto PARSE_OVER;
  }
H
hzcheng 已提交
4615

4616
  if (INSERT_TEST == g_args.test_mode) {
4617
    ret = getMetaFromInsertJsonFile(root);
4618
  } else if ((QUERY_TEST == g_args.test_mode)
4619
          || (SUBSCRIBE_TEST == g_args.test_mode)) {
4620 4621
    ret = getMetaFromQueryJsonFile(root);
  } else {
4622
    errorPrint("%s() LN%d, input json file type error! please input correct file type: insert or query or subscribe\n",
4623
            __func__, __LINE__);
4624
    goto PARSE_OVER;
4625
  }
4626

4627
PARSE_OVER:
4628 4629
  free(content);
  cJSON_Delete(root);
H
hzcheng 已提交
4630
  fclose(fp);
4631 4632
  return ret;
}
H
hzcheng 已提交
4633

4634
static void prepareSampleData() {
4635
  for (int i = 0; i < g_Dbs.dbCount; i++) {
4636 4637 4638
    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 已提交
4639
      }
4640 4641 4642 4643
    }
  }
}

4644
static void postFreeResource() {
4645
  tmfclose(g_fpOfInsertResult);
4646
  for (int i = 0; i < g_Dbs.dbCount; i++) {
S
Shuduo Sang 已提交
4647
    for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) {
4648 4649 4650
      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 已提交
4651
      }
4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663
      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 已提交
4664
    }
4665 4666
  }
}
S
Shuaiqiang Chang 已提交
4667

4668 4669 4670
static int getRowDataFromSample(
        char* dataBuf, int64_t maxLen, int64_t timestamp,
      SSuperTable* superTblInfo, int64_t* sampleUsePos) {
4671
  if ((*sampleUsePos) == MAX_SAMPLES_ONCE_FROM_FILE) {
4672
/*    int ret = readSampleFromCsvFileToMem(superTblInfo);
4673
    if (0 != ret) {
4674
      tmfree(superTblInfo->sampleDataBuf);
4675
      superTblInfo->sampleDataBuf = NULL;
4676 4677
      return -1;
    }
4678
*/
4679 4680
    *sampleUsePos = 0;
  }
S
Shuaiqiang Chang 已提交
4681

4682
  int    dataLen = 0;
4683

4684
  dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen,
4685
          "(%" PRId64 ", ", timestamp);
4686
  dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen,
4687
          "%s", superTblInfo->sampleDataBuf + superTblInfo->lenOfOneRow * (*sampleUsePos));
4688
  dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")");
S
Shuaiqiang Chang 已提交
4689

4690
  (*sampleUsePos)++;
4691

4692 4693
  return dataLen;
}
S
Shuaiqiang Chang 已提交
4694

4695 4696
static int64_t generateStbRowData(
        SSuperTable* stbInfo,
4697 4698
        char* recBuf, int64_t timestamp)
{
4699
  int64_t   dataLen = 0;
4700
  char  *pstr = recBuf;
4701
  int64_t maxLen = MAX_DATA_SIZE;
4702

4703 4704
  dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
          "(%" PRId64 ",", timestamp);
4705

4706
  for (int i = 0; i < stbInfo->columnCount; i++) {
4707 4708 4709 4710
    if ((0 == strncasecmp(stbInfo->columns[i].dataType,
                    "BINARY", strlen("BINARY")))
            || (0 == strncasecmp(stbInfo->columns[i].dataType,
                    "NCHAR", strlen("NCHAR")))) {
4711
      if (stbInfo->columns[i].dataLen > TSDB_MAX_BINARY_LEN) {
4712
        errorPrint( "binary or nchar length overflow, max size:%u\n",
4713
                (uint32_t)TSDB_MAX_BINARY_LEN);
4714
        return -1;
4715
      }
4716

4717 4718
      char* buf = (char*)calloc(stbInfo->columns[i].dataLen+1, 1);
      if (NULL == buf) {
4719
        errorPrint( "calloc failed! size:%d\n", stbInfo->columns[i].dataLen);
4720
        return -1;
4721 4722
      }
      rand_string(buf, stbInfo->columns[i].dataLen);
4723
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "\'%s\',", buf);
4724
      tmfree(buf);
4725
    } else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4726
                "INT", strlen("INT"))) {
4727
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4728
              "%d,", rand_int());
4729
    } else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4730
                "BIGINT", strlen("BIGINT"))) {
4731
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4732
              "%"PRId64",", rand_bigint());
4733
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4734
                "FLOAT", strlen("FLOAT"))) {
4735
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4736
              "%f,", rand_float());
4737
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4738
                "DOUBLE", strlen("DOUBLE"))) {
4739
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4740
              "%f,", rand_double());
4741
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4742
                "SMALLINT", strlen("SMALLINT"))) {
4743
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4744
          "%d,", rand_smallint());
4745
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4746
          "TINYINT", strlen("TINYINT"))) {
4747
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4748
          "%d,", rand_tinyint());
4749
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4750
          "BOOL", strlen("BOOL"))) {
4751
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4752
          "%d,", rand_bool());
4753
    }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
4754
          "TIMESTAMP", strlen("TIMESTAMP"))) {
4755
      dataLen += snprintf(pstr + dataLen, maxLen - dataLen,
4756
          "%"PRId64",", rand_bigint());
4757
    }  else {
4758
      errorPrint( "No support data type: %s\n", stbInfo->columns[i].dataType);
4759
      return -1;
4760
    }
S
Shuaiqiang Chang 已提交
4761
  }
4762

4763
  dataLen -= 1;
4764
  dataLen += snprintf(pstr + dataLen, maxLen - dataLen, ")");
4765

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

  return strlen(recBuf);
4769
}
S
Shuaiqiang Chang 已提交
4770

4771
static int64_t generateData(char *recBuf, char **data_type,
4772
        int64_t timestamp, int lenOfBinary) {
4773 4774
  memset(recBuf, 0, MAX_DATA_SIZE);
  char *pstr = recBuf;
4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788
  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);
  }

H
Haojun Liao 已提交
4789
  for (int i = 0; i < c; i++) {
4790 4791 4792 4793 4794 4795 4796 4797
    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());
4798 4799
    } else if (strcasecmp(data_type[i % c], "TIMESTAMP") == 0) {
      pstr += sprintf(pstr, ",%" PRId64, rand_bigint());
4800 4801 4802
    } 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) {
4803
      double t = rand_double();
4804 4805
      pstr += sprintf(pstr, ",%20.8f", t);
    } else if (strcasecmp(data_type[i % c], "BOOL") == 0) {
4806
      bool b = rand_bool() & 1;
4807 4808
      pstr += sprintf(pstr, ",%s", b ? "true" : "false");
    } else if (strcasecmp(data_type[i % c], "BINARY") == 0) {
4809 4810
      char *s = malloc(lenOfBinary);
      rand_string(s, lenOfBinary);
4811
      pstr += sprintf(pstr, ",\"%s\"", s);
4812
      free(s);
4813
    } else if (strcasecmp(data_type[i % c], "NCHAR") == 0) {
4814 4815
      char *s = malloc(lenOfBinary);
      rand_string(s, lenOfBinary);
4816
      pstr += sprintf(pstr, ",\"%s\"", s);
4817 4818 4819
      free(s);
    }

4820
    if (strlen(recBuf) > MAX_DATA_SIZE) {
4821 4822 4823 4824 4825 4826 4827
      perror("column length too long, abort");
      exit(-1);
    }
  }

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

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

4830
  return (int32_t)strlen(recBuf);
4831 4832
}

4833
static int prepareSampleDataForSTable(SSuperTable *superTblInfo) {
4834 4835
  char* sampleDataBuf = NULL;

4836
  sampleDataBuf = calloc(
4837
            superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, 1);
4838
  if (sampleDataBuf == NULL) {
4839
      errorPrint("%s() LN%d, Failed to calloc %"PRIu64" Bytes, reason:%s\n",
4840 4841 4842 4843
              __func__, __LINE__,
              superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE,
              strerror(errno));
      return -1;
4844
  }
4845

4846 4847 4848 4849
  superTblInfo->sampleDataBuf = sampleDataBuf;
  int ret = readSampleFromCsvFileToMem(superTblInfo);

  if (0 != ret) {
4850 4851 4852 4853 4854
      errorPrint("%s() LN%d, read sample from csv file failed.\n",
          __func__, __LINE__);
      tmfree(sampleDataBuf);
      superTblInfo->sampleDataBuf = NULL;
      return -1;
H
Hui Li 已提交
4855
  }
4856

4857 4858 4859
  return 0;
}

S
Shuduo Sang 已提交
4860
static int64_t execInsert(threadInfo *pThreadInfo, uint64_t k)
4861 4862
{
  int affectedRows;
4863
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
4864

4865
  verbosePrint("[%d] %s() LN%d %s\n", pThreadInfo->threadID,
S
Shuduo Sang 已提交
4866
            __func__, __LINE__, pThreadInfo->buffer);
4867
  if (superTblInfo) {
4868
    if (superTblInfo->iface == TAOSC_IFACE) {
S
Shuduo Sang 已提交
4869 4870 4871
      affectedRows = queryDbExec(
              pThreadInfo->taos,
              pThreadInfo->buffer, INSERT_TYPE, false);
4872
    } else if (superTblInfo->iface == REST_IFACE) {
4873
      if (0 != postProceSql(g_Dbs.host, &g_Dbs.serv_addr, g_Dbs.port,
S
Shuduo Sang 已提交
4874
                  pThreadInfo->buffer, NULL /* not set result file */)) {
4875
        affectedRows = -1;
4876
        printf("========restful return fail, threadID[%d]\n",
4877
            pThreadInfo->threadID);
4878 4879 4880
      } else {
        affectedRows = k;
      }
4881
    } else if (superTblInfo->iface == STMT_IFACE) {
S
Shuduo Sang 已提交
4882 4883 4884 4885 4886 4887
      debugPrint("%s() LN%d, stmt=%p", __func__, __LINE__, pThreadInfo->stmt);
      if (0 != taos_stmt_execute(pThreadInfo->stmt)) {
        errorPrint("%s() LN%d, failied to execute insert statement\n",
                    __func__, __LINE__);
        exit(-1);
      }
S
Shuduo Sang 已提交
4888 4889

      affectedRows = k;
4890
    } else {
4891
      errorPrint("%s() LN%d: unknown insert mode: %d\n",
4892
        __func__, __LINE__, superTblInfo->iface);
4893
      affectedRows = 0;
4894
    }
4895
  } else {
S
Shuduo Sang 已提交
4896
    affectedRows = queryDbExec(pThreadInfo->taos, pThreadInfo->buffer, INSERT_TYPE, false);
4897 4898 4899 4900 4901
  }

  return affectedRows;
}

4902 4903
static void getTableName(char *pTblName,
        threadInfo* pThreadInfo, uint64_t tableSeq)
4904 4905
{
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
4906 4907
  if ((superTblInfo)
          && (AUTO_CREATE_SUBTBL != superTblInfo->autoCreateTable)) {
4908
    if (superTblInfo->childTblLimit > 0) {
4909 4910 4911
        snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s",
            superTblInfo->childTblName +
            (tableSeq - superTblInfo->childTblOffset) * TSDB_TABLE_NAME_LEN);
4912
    } else {
4913

4914
        verbosePrint("[%d] %s() LN%d: from=%"PRIu64" count=%"PRId64" seq=%"PRIu64"\n",
4915 4916 4917 4918 4919
                pThreadInfo->threadID, __func__, __LINE__,
                pThreadInfo->start_table_from,
                pThreadInfo->ntables, tableSeq);
        snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s",
            superTblInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN);
4920 4921
    }
  } else {
4922
    snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%"PRIu64"",
4923
        g_args.tb_prefix, tableSeq);
4924 4925 4926
  }
}

4927
static int64_t generateDataTailWithoutStb(
4928
        uint32_t batch, char* buffer,
4929
        int64_t remainderBufLen, int64_t insertRows,
4930
        uint64_t recordFrom, int64_t startTime,
4931
        /* int64_t *pSamplePos, */int64_t *dataLen) {
4932

4933
  uint64_t len = 0;
4934 4935
  char *pstr = buffer;

4936
  verbosePrint("%s() LN%d batch=%d\n", __func__, __LINE__, batch);
4937

4938
  int64_t k = 0;
4939
  for (k = 0; k < batch;) {
4940
    char data[MAX_DATA_SIZE];
4941 4942
    memset(data, 0, MAX_DATA_SIZE);

4943
    int64_t retLen = 0;
4944

4945 4946
    char **data_type = g_args.datatype;
    int lenOfBinary = g_args.len_of_binary;
4947

4948
    retLen = generateData(data, data_type,
4949 4950 4951 4952
            startTime + getTSRandTail(
                (int64_t)DEFAULT_TIMESTAMP_STEP, k,
                g_args.disorderRatio,
                g_args.disorderRange),
4953
            lenOfBinary);
4954

4955
    if (len > remainderBufLen)
4956
        break;
4957

4958 4959 4960 4961 4962 4963 4964
    pstr += sprintf(pstr, "%s", data);
    k++;
    len += retLen;
    remainderBufLen -= retLen;

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

4966
    recordFrom ++;
4967

4968
    if (recordFrom >= insertRows) {
4969 4970 4971
      break;
    }
  }
4972

4973 4974 4975 4976
  *dataLen = len;
  return k;
}

4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993
static int64_t getTSRandTail(int64_t timeStampStep, int32_t seq,
        int disorderRatio, int disorderRange)
{
    int64_t randTail = timeStampStep * seq;
    if (disorderRatio > 0) {
        int rand_num = taosRandom() % 100;
        if(rand_num < disorderRatio) {
            randTail = (randTail +
                    (taosRandom() % disorderRange + 1)) * (-1);
            debugPrint("rand data generated, back %"PRId64"\n", randTail);
        }
    }

    return randTail;
}

static int32_t generateStbDataTail(
4994
        SSuperTable* superTblInfo,
4995
        uint32_t batch, char* buffer,
4996
        int64_t remainderBufLen, int64_t insertRows,
4997
        uint64_t recordFrom, int64_t startTime,
4998 4999 5000 5001 5002
        int64_t *pSamplePos, int64_t *dataLen) {
  uint64_t len = 0;

  char *pstr = buffer;

5003 5004 5005 5006 5007 5008 5009
  bool tsRand;
  if (0 == strncasecmp(superTblInfo->dataSource, "rand", strlen("rand"))) {
      tsRand = true;
  } else {
      tsRand = false;
  }
  verbosePrint("%s() LN%d batch=%ud\n", __func__, __LINE__, batch);
5010

5011
  int32_t k = 0;
5012 5013 5014 5015 5016 5017
  for (k = 0; k < batch;) {
    char data[MAX_DATA_SIZE];
    memset(data, 0, MAX_DATA_SIZE);

    int64_t retLen = 0;

5018 5019 5020 5021 5022 5023 5024 5025 5026
    if (tsRand) {
        retLen = generateStbRowData(superTblInfo, data,
                startTime + getTSRandTail(
                    superTblInfo->timeStampStep, k,
                    superTblInfo->disorderRatio,
                    superTblInfo->disorderRange)
                );
    } else {
        retLen = getRowDataFromSample(
5027 5028 5029 5030 5031 5032
                  data,
                  remainderBufLen,
                  startTime + superTblInfo->timeStampStep * k,
                  superTblInfo,
                  pSamplePos);
    }
5033

5034
    if (retLen > remainderBufLen) {
5035
        break;
5036 5037
    }

5038 5039 5040 5041 5042
    pstr += snprintf(pstr , retLen + 1, "%s", data);
    k++;
    len += retLen;
    remainderBufLen -= retLen;

5043
    verbosePrint("%s() LN%d len=%"PRIu64" k=%ud \nbuffer=%s\n",
5044
            __func__, __LINE__, len, k, buffer);
5045

5046
    recordFrom ++;
5047

5048
    if (recordFrom >= insertRows) {
5049
      break;
5050
    }
5051
  }
5052

5053 5054 5055
  *dataLen = len;
  return k;
}
5056

5057 5058 5059

static int generateSQLHeadWithoutStb(char *tableName,
        char *dbName,
5060
        char *buffer, int remainderBufLen)
5061 5062
{
  int len;
5063 5064 5065

  char headBuf[HEAD_BUFF_LEN];

5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091
  len = snprintf(
          headBuf,
          HEAD_BUFF_LEN,
          "%s.%s values",
          dbName,
          tableName);

  if (len > remainderBufLen)
    return -1;

  tstrncpy(buffer, headBuf, len + 1);

  return len;
}

static int generateStbSQLHead(
        SSuperTable* superTblInfo,
        char *tableName, int32_t tableSeq,
        char *dbName,
        char *buffer, int remainderBufLen)
{
  int len;

  char headBuf[HEAD_BUFF_LEN];

  if (AUTO_CREATE_SUBTBL == superTblInfo->autoCreateTable) {
5092 5093
      char* tagsValBuf = NULL;
      if (0 == superTblInfo->tagSource) {
5094
            tagsValBuf = generateTagVaulesForStb(superTblInfo, tableSeq);
5095
      } else {
5096 5097 5098
            tagsValBuf = getTagValueFromTagSample(
                    superTblInfo,
                    tableSeq % superTblInfo->tagSampleCount);
5099 5100
      }
      if (NULL == tagsValBuf) {
5101
        errorPrint("%s() LN%d, tag buf failed to allocate  memory\n",
5102
            __func__, __LINE__);
5103 5104 5105
        return -1;
      }

5106 5107
      len = snprintf(
          headBuf,
5108 5109
                  HEAD_BUFF_LEN,
                  "%s.%s using %s.%s tags %s values",
5110
                  dbName,
5111
                  tableName,
5112
                  dbName,
5113 5114
                  superTblInfo->sTblName,
                  tagsValBuf);
5115 5116
      tmfree(tagsValBuf);
    } else if (TBL_ALREADY_EXISTS == superTblInfo->childTblExists) {
5117 5118
      len = snprintf(
          headBuf,
5119 5120
                  HEAD_BUFF_LEN,
                  "%s.%s values",
5121
                  dbName,
5122
                  tableName);
5123
    } else {
5124 5125
      len = snprintf(
          headBuf,
5126 5127
                  HEAD_BUFF_LEN,
                  "%s.%s values",
5128
                  dbName,
5129
                  tableName);
5130 5131
  }

5132 5133 5134 5135 5136
  if (len > remainderBufLen)
    return -1;

  tstrncpy(buffer, headBuf, len + 1);

5137 5138 5139
  return len;
}

5140
static int32_t generateStbInterlaceData(
5141
        SSuperTable *superTblInfo,
5142 5143 5144
        char *tableName, uint32_t batchPerTbl,
        uint64_t i,
        uint32_t batchPerTblTimes,
5145
        uint64_t tableSeq,
5146
        threadInfo *pThreadInfo, char *buffer,
5147
        int64_t insertRows,
5148
        int64_t startTime,
5149
        uint64_t *pRemainderBufLen)
5150
{
5151
  assert(buffer);
5152 5153
  char *pstr = buffer;

5154 5155 5156
  int headLen = generateStbSQLHead(
          superTblInfo,
          tableName, tableSeq, pThreadInfo->db_name,
5157
          pstr, *pRemainderBufLen);
5158 5159 5160 5161 5162

  if (headLen <= 0) {
    return 0;
  }
  // generate data buffer
5163
  verbosePrint("[%d] %s() LN%d i=%"PRIu64" buffer:\n%s\n",
5164
            pThreadInfo->threadID, __func__, __LINE__, i, buffer);
5165 5166 5167 5168

  pstr += headLen;
  *pRemainderBufLen -= headLen;

5169
  int64_t dataLen = 0;
5170

5171
  verbosePrint("[%d] %s() LN%d i=%"PRIu64" batchPerTblTimes=%ud batchPerTbl = %ud\n",
5172 5173
            pThreadInfo->threadID, __func__, __LINE__,
            i, batchPerTblTimes, batchPerTbl);
5174

5175
  if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) {
5176
      startTime = taosGetTimestamp(pThreadInfo->time_precision);
5177
  }
5178

5179
  int32_t k = generateStbDataTail(
5180 5181 5182 5183
            superTblInfo,
            batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0,
            startTime,
            &(pThreadInfo->samplePos), &dataLen);
5184 5185 5186 5187

  if (k == batchPerTbl) {
    pstr += dataLen;
    *pRemainderBufLen -= dataLen;
5188
  } else {
5189
    debugPrint("%s() LN%d, generated data tail: %ud, not equal batch per table: %ud\n",
5190 5191 5192 5193 5194 5195 5196 5197 5198 5199
            __func__, __LINE__, k, batchPerTbl);
    pstr -= headLen;
    pstr[0] = '\0';
    k = 0;
  }

  return k;
}

static int64_t generateInterlaceDataWithoutStb(
5200
        char *tableName, uint32_t batchPerTbl,
5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223
        uint64_t tableSeq,
        char *dbName, char *buffer,
        int64_t insertRows,
        uint64_t *pRemainderBufLen)
{
  assert(buffer);
  char *pstr = buffer;

  int headLen = generateSQLHeadWithoutStb(
          tableName, dbName,
            pstr, *pRemainderBufLen);

  if (headLen <= 0) {
    return 0;
  }

  pstr += headLen;
  *pRemainderBufLen -= headLen;

  int64_t dataLen = 0;

  int64_t startTime = 1500000000000;
  int64_t  k = generateDataTailWithoutStb(
5224 5225
            batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0,
            startTime,
5226
            &dataLen);
5227 5228

  if (k == batchPerTbl) {
5229 5230 5231
    pstr += dataLen;
    *pRemainderBufLen -= dataLen;
  } else {
5232
    debugPrint("%s() LN%d, generated data tail: %"PRIu64", not equal batch per table: %ud\n",
5233
            __func__, __LINE__, k, batchPerTbl);
5234 5235
    pstr -= headLen;
    pstr[0] = '\0';
5236
    k = 0;
5237 5238 5239 5240 5241
  }

  return k;
}

5242 5243 5244
static int32_t prepareStbStmt(SSuperTable *stbInfo,
        TAOS_STMT *stmt,
        char *tableName, uint32_t batch, uint64_t insertRows,
5245
        uint64_t recordFrom,
5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264
        int64_t startTime, char *buffer)
{
    uint32_t k;
    int      ret;
    char *pstr = buffer;
    pstr += sprintf(pstr, "INSERT INTO %s values(?", tableName);

    for (int i = 0; i < stbInfo->columnCount; i++) {
        pstr += sprintf(pstr, ",?");
    }
    pstr += sprintf(pstr, ")");

    ret = taos_stmt_prepare(stmt, buffer, 0);
    if (ret != 0){
        errorPrint("failed to execute taos_stmt_prepare. return 0x%x. reason: %s\n",
                ret, taos_errstr(NULL));
        return ret;
    }

5265
    char *bindArray = malloc(sizeof(TAOS_BIND) * (stbInfo->columnCount + 1));
5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276
    if (bindArray == NULL) {
        errorPrint("Failed to allocate %d bind params\n", batch);
        return -1;
    }

    bool tsRand;
    if (0 == strncasecmp(stbInfo->dataSource, "rand", strlen("rand"))) {
        tsRand = true;
    } else {
        tsRand = false;
    }
5277
    for (k = 0; k < batch;) {
5278
        /* columnCount + 1 (ts) */
5279 5280 5281 5282 5283
        char data[MAX_DATA_SIZE];
        memset(data, 0, MAX_DATA_SIZE);

        char *ptr = data;
        TAOS_BIND *bind = (TAOS_BIND *)(bindArray + 0);
5284

5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434
        int64_t *bind_ts;

        bind_ts = (int64_t *)ptr;
        bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
        if (tsRand) {
            *bind_ts = startTime + getTSRandTail(
                    stbInfo->timeStampStep, k,
                    stbInfo->disorderRatio,
                    stbInfo->disorderRange);
        } else {
            *bind_ts = startTime + stbInfo->timeStampStep * k;
        }
        bind->buffer_length = sizeof(int64_t);
        bind->buffer = bind_ts;
        bind->length = &bind->buffer_length;
        bind->is_null = NULL;

        ptr += bind->buffer_length;

        for (int i = 0; i < stbInfo->columnCount; i ++) {
            bind = (TAOS_BIND *)((char *)bindArray + (sizeof(TAOS_BIND) * (i + 1)));
            if (0 == strncasecmp(stbInfo->columns[i].dataType,
                        "BINARY", strlen("BINARY"))) {
                if (stbInfo->columns[i].dataLen > TSDB_MAX_BINARY_LEN) {
                    errorPrint( "binary length overflow, max size:%u\n",
                            (uint32_t)TSDB_MAX_BINARY_LEN);
                    return -1;
                }
                char *bind_binary = (char *)ptr;
                rand_string(bind_binary, stbInfo->columns[i].dataLen);

                bind->buffer_type = TSDB_DATA_TYPE_BINARY;
                bind->buffer_length = stbInfo->columns[i].dataLen;
                bind->buffer = bind_binary;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;

                ptr += bind->buffer_length;
            } else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                        "NCHAR", strlen("NCHAR"))) {
                if (stbInfo->columns[i].dataLen > TSDB_MAX_BINARY_LEN) {
                    errorPrint( "nchar length overflow, max size:%u\n",
                            (uint32_t)TSDB_MAX_BINARY_LEN);
                    return -1;
                }
                char *bind_nchar = (char *)ptr;
                rand_string(bind_nchar, stbInfo->columns[i].dataLen);

                bind->buffer_type = TSDB_DATA_TYPE_NCHAR;
                bind->buffer_length = strlen(bind_nchar);
                bind->buffer = bind_nchar;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;

                ptr += bind->buffer_length;
            } else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                        "INT", strlen("INT"))) {
                int32_t *bind_int = (int32_t *)ptr;

                *bind_int = rand_int();
                bind->buffer_type = TSDB_DATA_TYPE_INT;
                bind->buffer_length = sizeof(int32_t);
                bind->buffer = bind_int;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;

                ptr += bind->buffer_length;
            } else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                            "BIGINT", strlen("BIGINT"))) {
                int64_t *bind_bigint = (int64_t *)ptr;

                *bind_bigint = rand_bigint();
                bind->buffer_type = TSDB_DATA_TYPE_BIGINT;
                bind->buffer_length = sizeof(int64_t);
                bind->buffer = bind_bigint;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;
                ptr += bind->buffer_length;
            }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                            "FLOAT", strlen("FLOAT"))) {
                float   *bind_float = (float *)ptr;

                *bind_float = rand_float();
                bind->buffer_type = TSDB_DATA_TYPE_FLOAT;
                bind->buffer_length = sizeof(float);
                bind->buffer = bind_float;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;
                ptr += bind->buffer_length;
            }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                            "DOUBLE", strlen("DOUBLE"))) {
                double  *bind_double = (double *)ptr;

                *bind_double = rand_double();
                bind->buffer_type = TSDB_DATA_TYPE_DOUBLE;
                bind->buffer_length = sizeof(double);
                bind->buffer = bind_double;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;
                ptr += bind->buffer_length;
            }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                            "SMALLINT", strlen("SMALLINT"))) {
                int16_t *bind_smallint = (int16_t *)ptr;

                *bind_smallint = rand_smallint();
                bind->buffer_type = TSDB_DATA_TYPE_SMALLINT;
                bind->buffer_length = sizeof(int16_t);
                bind->buffer = bind_smallint;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;
                ptr += bind->buffer_length;
            }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                            "TINYINT", strlen("TINYINT"))) {
                int8_t  *bind_tinyint = (int8_t *)ptr;

                *bind_tinyint = rand_tinyint();
                bind->buffer_type = TSDB_DATA_TYPE_TINYINT;
                bind->buffer_length = sizeof(int8_t);
                bind->buffer = bind_tinyint;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;
                ptr += bind->buffer_length;
            }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                            "BOOL", strlen("BOOL"))) {
                int8_t  *bind_bool = (int8_t *)ptr;

                *bind_bool = rand_bool();
                bind->buffer_type = TSDB_DATA_TYPE_BOOL;
                bind->buffer_length = sizeof(int8_t);
                bind->buffer = bind_bool;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;

                ptr += bind->buffer_length;
            }  else if (0 == strncasecmp(stbInfo->columns[i].dataType,
                            "TIMESTAMP", strlen("TIMESTAMP"))) {
                int64_t *bind_ts2 = (int64_t *)ptr;

                *bind_ts2 = rand_bigint();
                bind->buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
                bind->buffer_length = sizeof(int64_t);
                bind->buffer = bind_ts2;
                bind->length = &bind->buffer_length;
                bind->is_null = NULL;

                ptr += bind->buffer_length;
            }  else {
                    errorPrint( "No support data type: %s\n",
                            stbInfo->columns[i].dataType);
                    return -1;
5435 5436
            }
        }
5437
        taos_stmt_bind_param(stmt, (TAOS_BIND *)bindArray);
5438
        // if msg > 3MB, break
5439
        taos_stmt_add_batch(stmt);
5440

5441 5442 5443 5444 5445 5446
        k++;
        recordFrom ++;
        if (recordFrom >= insertRows) {
            break;
        }
    }
5447 5448 5449 5450 5451

    return k;
}

static int32_t generateStbProgressiveData(
5452
        SSuperTable *superTblInfo,
5453
        char *tableName,
5454
        int64_t tableSeq,
5455
        char *dbName, char *buffer,
5456
        int64_t insertRows,
5457
        uint64_t recordFrom, int64_t startTime, int64_t *pSamplePos,
5458
        int64_t *pRemainderBufLen)
5459 5460
{
  assert(buffer != NULL);
5461
  char *pstr = buffer;
5462

5463
  memset(buffer, 0, *pRemainderBufLen);
5464

5465
  int64_t headLen = generateStbSQLHead(
5466
              superTblInfo,
5467
          tableName, tableSeq, dbName,
5468
          buffer, *pRemainderBufLen);
5469 5470 5471 5472

  if (headLen <= 0) {
    return 0;
  }
5473
  pstr += headLen;
5474
  *pRemainderBufLen -= headLen;
5475

5476
  int64_t dataLen;
5477

5478
  return generateStbDataTail(superTblInfo,
5479
          g_args.num_of_RPR, pstr, *pRemainderBufLen,
5480
          insertRows, recordFrom,
5481 5482
          startTime,
          pSamplePos, &dataLen);
5483 5484
}

5485 5486 5487 5488 5489
static int64_t prepareStmtWithoutStb(char *tableName)
{
    return -1;
}

5490 5491
static int64_t generateProgressiveDataWithoutStb(
        char *tableName,
5492
        /* int64_t tableSeq, */
5493 5494
        threadInfo *pThreadInfo, char *buffer,
        int64_t insertRows,
5495
        uint64_t recordFrom, int64_t startTime, /*int64_t *pSamplePos, */
5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515
        int64_t *pRemainderBufLen)
{
  assert(buffer != NULL);
  char *pstr = buffer;

  memset(buffer, 0, *pRemainderBufLen);

  int64_t headLen = generateSQLHeadWithoutStb(
          tableName, pThreadInfo->db_name,
          buffer, *pRemainderBufLen);

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

  int64_t dataLen;

  return generateDataTailWithoutStb(
5516
          g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, recordFrom,
5517 5518
          startTime,
          /*pSamplePos, */&dataLen);
5519
}
5520

5521 5522 5523 5524 5525 5526 5527 5528 5529
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)));
}

5530
// sync write interlace data
5531
static void* syncWriteInterlace(threadInfo *pThreadInfo) {
5532
  debugPrint("[%d] %s() LN%d: ### interlace write\n",
5533 5534
         pThreadInfo->threadID, __func__, __LINE__);

5535
  int64_t insertRows;
5536
  uint32_t interlaceRows;
5537 5538 5539
  uint64_t maxSqlLen;
  int64_t nTimeStampStep;
  uint64_t insert_interval;
5540 5541

  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5542

5543 5544 5545 5546 5547 5548 5549 5550 5551
  if (superTblInfo) {
    insertRows = superTblInfo->insertRows;

    if ((superTblInfo->interlaceRows == 0)
        && (g_args.interlace_rows > 0)) {
      interlaceRows = g_args.interlace_rows;
    } else {
      interlaceRows = superTblInfo->interlaceRows;
    }
5552 5553 5554
    maxSqlLen = superTblInfo->maxSqlLen;
    nTimeStampStep = superTblInfo->timeStampStep;
    insert_interval = superTblInfo->insertInterval;
5555 5556 5557
  } else {
    insertRows = g_args.num_of_DPT;
    interlaceRows = g_args.interlace_rows;
5558 5559 5560
    maxSqlLen = g_args.max_sql_len;
    nTimeStampStep = DEFAULT_TIMESTAMP_STEP;
    insert_interval = g_args.insert_interval;
5561
  }
5562

5563 5564 5565 5566 5567
  debugPrint("[%d] %s() LN%d: start_table_from=%"PRIu64" ntables=%"PRId64" insertRows=%"PRIu64"\n",
          pThreadInfo->threadID, __func__, __LINE__,
          pThreadInfo->start_table_from,
          pThreadInfo->ntables, insertRows);

5568
  if (interlaceRows > insertRows)
H
Haojun Liao 已提交
5569
    interlaceRows = insertRows;
5570

5571 5572
  if (interlaceRows > g_args.num_of_RPR)
    interlaceRows = g_args.num_of_RPR;
5573

5574 5575
  uint32_t batchPerTbl = interlaceRows;
  uint32_t batchPerTblTimes;
5576

5577 5578 5579
  if ((interlaceRows > 0) && (pThreadInfo->ntables > 1)) {
    batchPerTblTimes =
        g_args.num_of_RPR / interlaceRows;
5580
  } else {
5581
    batchPerTblTimes = 1;
5582 5583
  }

S
Shuduo Sang 已提交
5584 5585
  pThreadInfo->buffer = calloc(maxSqlLen, 1);
  if (NULL == pThreadInfo->buffer) {
5586
    errorPrint( "%s() LN%d, Failed to alloc %"PRIu64" Bytes, reason:%s\n",
5587
              __func__, __LINE__, maxSqlLen, strerror(errno));
5588 5589 5590 5591 5592 5593
    return NULL;
  }

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

5594 5595
  uint64_t st = 0;
  uint64_t et = UINT64_MAX;
5596

5597 5598 5599
  uint64_t lastPrintTime = taosGetTimestampMs();
  uint64_t startTs = taosGetTimestampMs();
  uint64_t endTs;
5600

5601
  uint64_t tableSeq = pThreadInfo->start_table_from;
5602 5603
  int64_t startTime = pThreadInfo->start_time;

5604
  uint64_t generatedRecPerTbl = 0;
5605
  bool flagSleep = true;
5606
  uint64_t sleepTimeTotal = 0;
5607

5608
  while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) {
5609
    if ((flagSleep) && (insert_interval)) {
5610 5611
        st = taosGetTimestampMs();
        flagSleep = false;
5612 5613
    }
    // generate data
S
Shuduo Sang 已提交
5614
    memset(pThreadInfo->buffer, 0, maxSqlLen);
5615
    uint64_t remainderBufLen = maxSqlLen;
5616

S
Shuduo Sang 已提交
5617
    char *pstr = pThreadInfo->buffer;
5618

5619 5620
    int len = snprintf(pstr,
            strlen(STR_INSERT_INTO) + 1, "%s", STR_INSERT_INTO);
5621 5622 5623
    pstr += len;
    remainderBufLen -= len;

5624
    uint32_t recOfBatch = 0;
5625

5626
    for (uint32_t i = 0; i < batchPerTblTimes; i ++) {
5627 5628
        char tableName[TSDB_TABLE_NAME_LEN];

5629
      getTableName(tableName, pThreadInfo, tableSeq);
5630 5631
      if (0 == strlen(tableName)) {
        errorPrint("[%d] %s() LN%d, getTableName return null\n",
5632
            pThreadInfo->threadID, __func__, __LINE__);
S
Shuduo Sang 已提交
5633
        free(pThreadInfo->buffer);
5634 5635
        return NULL;
      }
5636

5637
      uint64_t oldRemainderLen = remainderBufLen;
5638

5639
      int32_t generated;
5640 5641 5642
      if (superTblInfo) {
        generated = generateStbInterlaceData(
                superTblInfo,
5643 5644
                tableName, batchPerTbl, i,
                batchPerTblTimes,
5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657
                tableSeq,
                pThreadInfo, pstr,
                insertRows,
                startTime,
                &remainderBufLen);
      } else {
        generated = generateInterlaceDataWithoutStb(
                tableName, batchPerTbl,
                tableSeq,
                pThreadInfo->db_name, pstr,
                insertRows,
                &remainderBufLen);
      }
5658

5659
      debugPrint("[%d] %s() LN%d, generated records is %d\n",
5660
                  pThreadInfo->threadID, __func__, __LINE__, generated);
5661
      if (generated < 0) {
5662
        errorPrint("[%d] %s() LN%d, generated records is %d\n",
5663
                  pThreadInfo->threadID, __func__, __LINE__, generated);
5664
        goto free_of_interlace;
5665 5666
      } else if (generated == 0) {
        break;
5667 5668
      }

5669
      tableSeq ++;
5670
      recOfBatch += batchPerTbl;
5671
      pstr += (oldRemainderLen - remainderBufLen);
5672
//      startTime += batchPerTbl * superTblInfo->timeStampStep;
5673
      pThreadInfo->totalInsertRows += batchPerTbl;
5674
      verbosePrint("[%d] %s() LN%d batchPerTbl=%d recOfBatch=%d\n",
5675 5676
                pThreadInfo->threadID, __func__, __LINE__,
                batchPerTbl, recOfBatch);
5677

5678
      if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) {
5679 5680 5681
            // turn to first table
            tableSeq = pThreadInfo->start_table_from;
            generatedRecPerTbl += batchPerTbl;
5682

5683 5684
            startTime = pThreadInfo->start_time
              + generatedRecPerTbl * nTimeStampStep;
5685

5686 5687 5688
            flagSleep = true;
            if (generatedRecPerTbl >= insertRows)
              break;
5689

5690
            int64_t remainRows = insertRows - generatedRecPerTbl;
5691 5692
            if ((remainRows > 0) && (batchPerTbl > remainRows))
              batchPerTbl = remainRows;
5693

5694 5695 5696
            if (pThreadInfo->ntables * batchPerTbl < g_args.num_of_RPR)
                break;
      }
5697

5698
      verbosePrint("[%d] %s() LN%d generatedRecPerTbl=%"PRId64" insertRows=%"PRId64"\n",
5699 5700
                pThreadInfo->threadID, __func__, __LINE__,
                generatedRecPerTbl, insertRows);
5701 5702

      if ((g_args.num_of_RPR - recOfBatch) < batchPerTbl)
5703 5704 5705
        break;
    }

5706
    verbosePrint("[%d] %s() LN%d recOfBatch=%d totalInsertRows=%"PRIu64"\n",
5707 5708
              pThreadInfo->threadID, __func__, __LINE__, recOfBatch,
              pThreadInfo->totalInsertRows);
5709
    verbosePrint("[%d] %s() LN%d, buffer=%s\n",
S
Shuduo Sang 已提交
5710
           pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->buffer);
5711

5712
    startTs = taosGetTimestampMs();
5713

5714
    if (recOfBatch == 0) {
5715
      errorPrint("[%d] %s() LN%d try inserting records of batch is %d\n",
5716 5717 5718 5719 5720
              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;
    }
S
Shuduo Sang 已提交
5721
    int64_t affectedRows = execInsert(pThreadInfo, recOfBatch);
5722

5723
    endTs = taosGetTimestampMs();
5724 5725
    uint64_t delay = endTs - startTs;
    performancePrint("%s() LN%d, insert execution time is %"PRIu64"ms\n",
5726
            __func__, __LINE__, delay);
5727 5728 5729
    verbosePrint("[%d] %s() LN%d affectedRows=%"PRId64"\n",
            pThreadInfo->threadID,
            __func__, __LINE__, affectedRows);
5730 5731 5732 5733 5734 5735

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

5736
    if (recOfBatch != affectedRows) {
5737
        errorPrint("[%d] %s() LN%d execInsert insert %d, affected rows: %"PRId64"\n%s\n",
5738
                pThreadInfo->threadID, __func__, __LINE__,
S
Shuduo Sang 已提交
5739
                recOfBatch, affectedRows, pThreadInfo->buffer);
5740
        goto free_of_interlace;
5741
    }
5742

5743
    pThreadInfo->totalAffectedRows += affectedRows;
5744

5745 5746
    int64_t  currentPrintTime = taosGetTimestampMs();
    if (currentPrintTime - lastPrintTime > 30*1000) {
5747
      printf("thread[%d] has currently inserted rows: %"PRIu64 ", affected rows: %"PRIu64 "\n",
5748 5749 5750
                    pThreadInfo->threadID,
                    pThreadInfo->totalInsertRows,
                    pThreadInfo->totalAffectedRows);
5751 5752
      lastPrintTime = currentPrintTime;
    }
5753

5754
    if ((insert_interval) && flagSleep) {
5755
      et = taosGetTimestampMs();
5756

5757
      if (insert_interval > (et - st) ) {
S
Shuduo Sang 已提交
5758 5759
        uint64_t sleepTime = insert_interval - (et -st);
        performancePrint("%s() LN%d sleep: %"PRId64" ms for insert interval\n",
5760
                    __func__, __LINE__, sleepTime);
5761 5762 5763
        taosMsleep(sleepTime); // ms
        sleepTimeTotal += insert_interval;
      }
5764
    }
5765 5766
  }

5767
free_of_interlace:
S
Shuduo Sang 已提交
5768
  tmfree(pThreadInfo->buffer);
5769
  printStatPerThread(pThreadInfo);
5770 5771 5772
  return NULL;
}

5773
// sync insertion progressive data
5774
static void* syncWriteProgressive(threadInfo *pThreadInfo) {
5775
  debugPrint("%s() LN%d: ### progressive write\n", __func__, __LINE__);
5776

5777
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5778
  uint64_t maxSqlLen = superTblInfo?superTblInfo->maxSqlLen:g_args.max_sql_len;
5779 5780 5781 5782 5783 5784
  int64_t timeStampStep =
      superTblInfo?superTblInfo->timeStampStep:DEFAULT_TIMESTAMP_STEP;
  int64_t insertRows =
        (superTblInfo)?superTblInfo->insertRows:g_args.num_of_DPT;
  verbosePrint("%s() LN%d insertRows=%"PRId64"\n",
            __func__, __LINE__, insertRows);
5785

S
Shuduo Sang 已提交
5786 5787
  pThreadInfo->buffer = calloc(maxSqlLen, 1);
  if (NULL == pThreadInfo->buffer) {
5788
    errorPrint( "Failed to alloc %"PRIu64" Bytes, reason:%s\n",
5789 5790
              maxSqlLen,
              strerror(errno));
5791 5792
    return NULL;
  }
5793

5794 5795 5796
  uint64_t lastPrintTime = taosGetTimestampMs();
  uint64_t startTs = taosGetTimestampMs();
  uint64_t endTs;
5797

5798 5799
  pThreadInfo->totalInsertRows = 0;
  pThreadInfo->totalAffectedRows = 0;
5800

5801
  pThreadInfo->samplePos = 0;
5802

5803 5804 5805
  for (uint64_t tableSeq = pThreadInfo->start_table_from;
          tableSeq <= pThreadInfo->end_table_to;
          tableSeq ++) {
5806
    int64_t start_time = pThreadInfo->start_time;
5807

5808
    for (uint64_t i = 0; i < insertRows;) {
5809 5810
      char tableName[TSDB_TABLE_NAME_LEN];
      getTableName(tableName, pThreadInfo, tableSeq);
5811
      verbosePrint("%s() LN%d: tid=%d seq=%"PRId64" tableName=%s\n",
5812 5813
             __func__, __LINE__,
             pThreadInfo->threadID, tableSeq, tableName);
5814

5815
      int64_t remainderBufLen = maxSqlLen;
S
Shuduo Sang 已提交
5816
      char *pstr = pThreadInfo->buffer;
5817

5818 5819
      int len = snprintf(pstr,
              strlen(STR_INSERT_INTO) + 1, "%s", STR_INSERT_INTO);
5820 5821 5822 5823

      pstr += len;
      remainderBufLen -= len;

5824
      int32_t generated;
5825
      if (superTblInfo) {
5826 5827 5828 5829
          if (superTblInfo->iface == STMT_IFACE) {
              generated = prepareStbStmt(superTblInfo,
                      pThreadInfo->stmt,
                      tableName, g_args.num_of_RPR,
5830
                      insertRows, i, start_time, pstr);
5831 5832 5833 5834 5835 5836 5837 5838
          } else {
              generated = generateStbProgressiveData(
                      superTblInfo,
                      tableName, tableSeq, pThreadInfo->db_name, pstr,
                      insertRows, i, start_time,
                      &(pThreadInfo->samplePos),
                      &remainderBufLen);
          }
5839
      } else {
5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850
          if (g_args.iface == STMT_IFACE) {
              generated = prepareStmtWithoutStb(tableName);
          } else {
              generated = generateProgressiveDataWithoutStb(
                      tableName,
                      /*  tableSeq, */
                      pThreadInfo, pstr, insertRows,
                      i, start_time,
                      /* &(pThreadInfo->samplePos), */
                      &remainderBufLen);
          }
5851
      }
5852 5853 5854
      if (generated > 0)
        i += generated;
      else
5855
        goto free_of_progressive;
5856

5857
      start_time +=  generated * timeStampStep;
5858
      pThreadInfo->totalInsertRows += generated;
5859

5860
      startTs = taosGetTimestampMs();
5861

S
Shuduo Sang 已提交
5862
      int64_t affectedRows = execInsert(pThreadInfo, generated);
5863

5864
      endTs = taosGetTimestampMs();
5865
      uint64_t delay = endTs - startTs;
5866
      performancePrint("%s() LN%d, insert execution time is %"PRId64"ms\n",
5867
              __func__, __LINE__, delay);
5868 5869 5870
      verbosePrint("[%d] %s() LN%d affectedRows=%"PRId64"\n",
            pThreadInfo->threadID,
            __func__, __LINE__, affectedRows);
5871

5872 5873 5874 5875
      if (delay > pThreadInfo->maxDelay) pThreadInfo->maxDelay = delay;
      if (delay < pThreadInfo->minDelay) pThreadInfo->minDelay = delay;
      pThreadInfo->cntDelay++;
      pThreadInfo->totalDelay += delay;
5876

5877 5878 5879 5880 5881
      if (affectedRows < 0) {
        errorPrint("%s() LN%d, affected rows: %"PRId64"\n",
                __func__, __LINE__, affectedRows);
        goto free_of_progressive;
      }
5882 5883 5884

      pThreadInfo->totalAffectedRows += affectedRows;

5885 5886
      int64_t  currentPrintTime = taosGetTimestampMs();
      if (currentPrintTime - lastPrintTime > 30*1000) {
5887
        printf("thread[%d] has currently inserted rows: %"PRId64 ", affected rows: %"PRId64 "\n",
5888 5889 5890
                    pThreadInfo->threadID,
                    pThreadInfo->totalInsertRows,
                    pThreadInfo->totalAffectedRows);
5891 5892 5893
        lastPrintTime = currentPrintTime;
      }

5894
      if (i >= insertRows)
5895 5896 5897
        break;
    }   // num_of_DPT

5898 5899
    if ((g_args.verbose_print) &&
      (tableSeq == pThreadInfo->ntables - 1) && (superTblInfo) &&
5900 5901
        (0 == strncasecmp(
                    superTblInfo->dataSource, "sample", strlen("sample")))) {
5902
          verbosePrint("%s() LN%d samplePos=%"PRId64"\n",
5903
                  __func__, __LINE__, pThreadInfo->samplePos);
5904
    }
5905
  } // tableSeq
5906

5907
free_of_progressive:
S
Shuduo Sang 已提交
5908
  tmfree(pThreadInfo->buffer);
5909
  printStatPerThread(pThreadInfo);
5910
  return NULL;
H
Hui Li 已提交
5911 5912
}

5913 5914
static void* syncWrite(void *sarg) {

5915 5916
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5917

5918
  uint32_t interlaceRows;
5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929

  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;
  }
5930

5931
  if (interlaceRows > 0) {
5932
    // interlace mode
5933
    return syncWriteInterlace(pThreadInfo);
5934 5935
  } else {
    // progressive mode
5936
    return syncWriteProgressive(pThreadInfo);
5937 5938 5939
  }
}

5940
static void callBack(void *param, TAOS_RES *res, int code) {
5941 5942
  threadInfo* pThreadInfo = (threadInfo*)param;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
5943

5944 5945
  int insert_interval =
      superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
5946
  if (insert_interval) {
5947 5948 5949
    pThreadInfo->et = taosGetTimestampMs();
    if ((pThreadInfo->et - pThreadInfo->st) < insert_interval) {
      taosMsleep(insert_interval - (pThreadInfo->et - pThreadInfo->st)); // ms
5950
    }
H
Hui Li 已提交
5951
  }
5952

5953
  char *buffer = calloc(1, pThreadInfo->superTblInfo->maxSqlLen);
5954
  char data[MAX_DATA_SIZE];
5955
  char *pstr = buffer;
5956 5957
  pstr += sprintf(pstr, "insert into %s.%s%"PRId64" values",
          pThreadInfo->db_name, pThreadInfo->tb_prefix,
5958
          pThreadInfo->start_table_from);
5959 5960 5961 5962 5963 5964 5965
//  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);
5966 5967 5968 5969
    free(buffer);
    taos_free_result(res);
    return;
  }
5970

5971
  for (int i = 0; i < g_args.num_of_RPR; i++) {
5972
    int rand_num = taosRandom() % 100;
5973
    if (0 != pThreadInfo->superTblInfo->disorderRatio
5974
            && rand_num < pThreadInfo->superTblInfo->disorderRatio) {
5975 5976 5977
      int64_t d = pThreadInfo->lastTs
          - (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1);
      generateStbRowData(pThreadInfo->superTblInfo, data, d);
5978
    } else {
5979 5980
      generateStbRowData(pThreadInfo->superTblInfo,
              data, pThreadInfo->lastTs += 1000);
H
Hui Li 已提交
5981
    }
5982
    pstr += sprintf(pstr, "%s", data);
5983
    pThreadInfo->counter++;
H
Hui Li 已提交
5984

5985
    if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) {
5986
      break;
H
Hui Li 已提交
5987 5988
    }
  }
5989

5990
  if (insert_interval) {
5991
    pThreadInfo->st = taosGetTimestampMs();
5992
  }
5993
  taos_query_a(pThreadInfo->taos, buffer, callBack, pThreadInfo);
5994
  free(buffer);
H
Hui Li 已提交
5995

5996
  taos_free_result(res);
H
Hui Li 已提交
5997 5998
}

5999
static void *asyncWrite(void *sarg) {
6000 6001
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  SSuperTable* superTblInfo = pThreadInfo->superTblInfo;
6002

6003 6004 6005
  pThreadInfo->st = 0;
  pThreadInfo->et = 0;
  pThreadInfo->lastTs = pThreadInfo->start_time;
6006

6007
  int insert_interval =
6008
      superTblInfo?superTblInfo->insertInterval:g_args.insert_interval;
6009
  if (insert_interval) {
6010
    pThreadInfo->st = taosGetTimestampMs();
H
Hui Li 已提交
6011
  }
6012
  taos_query_a(pThreadInfo->taos, "show databases", callBack, pThreadInfo);
6013

6014
  tsem_wait(&(pThreadInfo->lock_sem));
H
Hui Li 已提交
6015 6016 6017 6018

  return NULL;
}

6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044
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;
}

6045
static void startMultiThreadInsertData(int threads, char* db_name,
6046
        char* precision,SSuperTable* superTblInfo) {
6047

6048
  //TAOS* taos;
6049
  //if (0 == strncasecmp(superTblInfo->iface, "taosc", 5)) {
6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063
  //  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 {
6064
      errorPrint("Not support precision: %s\n", precision);
6065 6066 6067 6068
      exit(-1);
    }
  }

6069
  int64_t start_time;
6070 6071
  if (superTblInfo) {
    if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) {
6072
        start_time = taosGetTimestamp(timePrec);
6073
    } else {
6074
      if (TSDB_CODE_SUCCESS != taosParseTime(
6075 6076 6077 6078 6079
        superTblInfo->startTimestamp,
        &start_time,
        strlen(superTblInfo->startTimestamp),
        timePrec, 0)) {
          ERROR_EXIT("failed to parse time!\n");
6080
      }
6081
    }
6082
  } else {
6083
     start_time = 1500000000000;
6084 6085
  }

6086
  int64_t start = taosGetTimestampMs();
6087

6088
  // read sample data from file first
6089
  if ((superTblInfo) && (0 == strncasecmp(superTblInfo->dataSource,
6090
              "sample", strlen("sample")))) {
6091
    if (0 != prepareSampleDataForSTable(superTblInfo)) {
6092
      errorPrint("%s() LN%d, prepare sample data for stable failed!\n",
6093
              __func__, __LINE__);
6094 6095 6096 6097
      exit(-1);
    }
  }

6098
  // read sample data from file first
6099
  if ((superTblInfo) && (0 == strncasecmp(superTblInfo->dataSource,
6100
              "sample", strlen("sample")))) {
6101
    if (0 != prepareSampleDataForSTable(superTblInfo)) {
6102
      errorPrint("%s() LN%d, prepare sample data for stable failed!\n",
6103
              __func__, __LINE__);
6104 6105 6106 6107
      exit(-1);
    }
  }

6108
  TAOS* taos0 = taos_connect(
6109 6110
              g_Dbs.host, g_Dbs.user,
              g_Dbs.password, db_name, g_Dbs.port);
6111
  if (NULL == taos0) {
6112
    errorPrint("%s() LN%d, connect to server fail , reason: %s\n",
6113
                __func__, __LINE__, taos_errstr(NULL));
6114 6115 6116
    exit(-1);
  }

S
Shuduo Sang 已提交
6117
  int64_t ntables = 0;
6118
  uint64_t tableFrom;
6119

6120
  if (superTblInfo) {
6121 6122
    int64_t limit;
    uint64_t offset;
6123

H
Haojun Liao 已提交
6124
    if ((NULL != g_args.sqlFile) && (superTblInfo->childTblExists == TBL_NO_EXISTS) &&
6125
            ((superTblInfo->childTblOffset != 0) || (superTblInfo->childTblLimit >= 0))) {
H
Haojun Liao 已提交
6126
      printf("WARNING: offset and limit will not be used since the child tables not exists!\n");
6127 6128
    }

6129
    if (superTblInfo->childTblExists == TBL_ALREADY_EXISTS) {
6130 6131
      if ((superTblInfo->childTblLimit < 0)
          || ((superTblInfo->childTblOffset + superTblInfo->childTblLimit)
6132
            > (superTblInfo->childTblCount))) {
6133 6134 6135 6136 6137 6138
        superTblInfo->childTblLimit =
            superTblInfo->childTblCount - superTblInfo->childTblOffset;
      }

      offset = superTblInfo->childTblOffset;
      limit = superTblInfo->childTblLimit;
6139
    } else {
6140 6141
      limit = superTblInfo->childTblCount;
      offset = 0;
6142 6143
    }

6144
    ntables = limit;
6145
    tableFrom = offset;
6146

6147 6148 6149 6150
    if ((superTblInfo->childTblExists != TBL_NO_EXISTS)
        && ((superTblInfo->childTblOffset + superTblInfo->childTblLimit )
            > superTblInfo->childTblCount)) {
      printf("WARNING: specified offset + limit > child table count!\n");
6151
      prompt();
6152 6153 6154
    }

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

6160
    superTblInfo->childTblName = (char*)calloc(1,
6161
        limit * TSDB_TABLE_NAME_LEN);
6162
    if (superTblInfo->childTblName == NULL) {
6163
      errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__);
6164
      taos_close(taos0);
6165 6166 6167
      exit(-1);
    }

6168
    int64_t childTblCount;
6169
    getChildNameOfSuperTableWithLimitAndOffset(
6170
        taos0,
6171 6172 6173 6174
        db_name, superTblInfo->sTblName,
        &superTblInfo->childTblName, &childTblCount,
        limit,
        offset);
6175 6176
  } else {
    ntables = g_args.num_of_tables;
6177
    tableFrom = 0;
6178
  }
6179

6180
  taos_close(taos0);
6181

S
Shuduo Sang 已提交
6182
  int64_t a = ntables / threads;
6183 6184 6185 6186 6187
  if (a < 1) {
    threads = ntables;
    a = 1;
  }

S
Shuduo Sang 已提交
6188
  int64_t b = 0;
6189 6190 6191 6192
  if (threads != 0) {
    b = ntables % threads;
  }

6193
  if ((superTblInfo)
6194 6195 6196
      && (superTblInfo->iface == REST_IFACE)) {
      if (convertHostToServAddr(
                  g_Dbs.host, g_Dbs.port, &(g_Dbs.serv_addr)) != 0) {
6197 6198
        exit(-1);
      }
6199 6200
  }

6201 6202 6203 6204 6205 6206 6207 6208 6209
  pthread_t *pids = malloc(threads * sizeof(pthread_t));
  assert(pids != NULL);

  threadInfo *infos = calloc(1, threads * sizeof(threadInfo));
  assert(infos != NULL);

  memset(pids, 0, threads * sizeof(pthread_t));
  memset(infos, 0, threads * sizeof(threadInfo));

H
Hui Li 已提交
6210
  for (int i = 0; i < threads; i++) {
6211 6212 6213 6214 6215
    threadInfo *pThreadInfo = infos + i;
    pThreadInfo->threadID = i;
    tstrncpy(pThreadInfo->db_name, db_name, MAX_DB_NAME_SIZE);
    pThreadInfo->time_precision = timePrec;
    pThreadInfo->superTblInfo = superTblInfo;
6216

6217 6218
    pThreadInfo->start_time = start_time;
    pThreadInfo->minDelay = UINT64_MAX;
6219

6220
    if ((NULL == superTblInfo) ||
6221 6222
            (superTblInfo->iface != REST_IFACE)) {
      //t_info->taos = taos;
6223
      pThreadInfo->taos = taos_connect(
6224 6225
              g_Dbs.host, g_Dbs.user,
              g_Dbs.password, db_name, g_Dbs.port);
6226
      if (NULL == pThreadInfo->taos) {
6227
        errorPrint(
6228 6229
                "%s() LN%d, connect to server fail from insert sub thread, reason: %s\n",
                __func__, __LINE__,
6230
                taos_errstr(NULL));
6231
        free(infos);
6232 6233
        exit(-1);
      }
6234

6235
      if ((superTblInfo) && (superTblInfo->iface == STMT_IFACE)) {
6236 6237
        pThreadInfo->stmt = taos_stmt_init(pThreadInfo->taos);
        if (NULL == pThreadInfo->stmt) {
6238 6239 6240 6241 6242 6243 6244 6245 6246
            errorPrint(
                "%s() LN%d, failed init stmt, reason: %s\n",
                __func__, __LINE__,
                taos_errstr(NULL));
            free(pids);
            free(infos);
            exit(-1);
        }
      }
6247
    } else {
6248
      pThreadInfo->taos = NULL;
6249 6250
    }

6251
/*    if ((NULL == superTblInfo)
6252
            || (0 == superTblInfo->multiThreadWriteOneTbl)) {
6253
            */
6254
      pThreadInfo->start_table_from = tableFrom;
6255
      pThreadInfo->ntables = i<b?a+1:a;
6256 6257
      pThreadInfo->end_table_to = i < b ? tableFrom + a : tableFrom + a - 1;
      tableFrom = pThreadInfo->end_table_to + 1;
6258
/*    } else {
6259 6260 6261
      pThreadInfo->start_table_from = 0;
      pThreadInfo->ntables = superTblInfo->childTblCount;
      pThreadInfo->start_time = pThreadInfo->start_time + rand_int() % 10000 - rand_tinyint();
6262
    }
6263
*/
6264
    tsem_init(&(pThreadInfo->lock_sem), 0, 0);
6265
    if (ASYNC_MODE == g_Dbs.asyncMode) {
6266
      pthread_create(pids + i, NULL, asyncWrite, pThreadInfo);
6267
    } else {
6268
      pthread_create(pids + i, NULL, syncWrite, pThreadInfo);
6269
    }
H
Hui Li 已提交
6270
  }
6271

H
Hui Li 已提交
6272 6273 6274 6275
  for (int i = 0; i < threads; i++) {
    pthread_join(pids[i], NULL);
  }

6276 6277 6278 6279
  uint64_t totalDelay = 0;
  uint64_t maxDelay = 0;
  uint64_t minDelay = UINT64_MAX;
  uint64_t cntDelay = 1;
6280 6281
  double  avgDelay = 0;

H
Hui Li 已提交
6282
  for (int i = 0; i < threads; i++) {
6283
    threadInfo *pThreadInfo = infos + i;
6284

6285
    tsem_destroy(&(pThreadInfo->lock_sem));
6286

6287 6288
    if (pThreadInfo->stmt) {
      taos_stmt_close(pThreadInfo->stmt);
6289
    }
6290 6291
    tsem_destroy(&(pThreadInfo->lock_sem));
    taos_close(pThreadInfo->taos);
6292

6293
    debugPrint("%s() LN%d, [%d] totalInsert=%"PRIu64" totalAffected=%"PRIu64"\n",
6294
            __func__, __LINE__,
6295 6296
            pThreadInfo->threadID, pThreadInfo->totalInsertRows,
            pThreadInfo->totalAffectedRows);
6297
    if (superTblInfo) {
6298 6299
        superTblInfo->totalAffectedRows += pThreadInfo->totalAffectedRows;
        superTblInfo->totalInsertRows += pThreadInfo->totalInsertRows;
6300
    } else {
6301 6302
        g_args.totalAffectedRows += pThreadInfo->totalAffectedRows;
        g_args.totalInsertRows += pThreadInfo->totalInsertRows;
6303
    }
6304

6305 6306 6307 6308
    totalDelay  += pThreadInfo->totalDelay;
    cntDelay   += pThreadInfo->cntDelay;
    if (pThreadInfo->maxDelay > maxDelay) maxDelay = pThreadInfo->maxDelay;
    if (pThreadInfo->minDelay < minDelay) minDelay = pThreadInfo->minDelay;
H
Hui Li 已提交
6309
  }
6310
  cntDelay -= 1;
H
Hui Li 已提交
6311

6312
  if (cntDelay == 0)    cntDelay = 1;
6313 6314
  avgDelay = (double)totalDelay / cntDelay;

6315 6316
  int64_t end = taosGetTimestampMs();
  int64_t t = end - start;
6317 6318

  if (superTblInfo) {
6319
    fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s.%s. %.2f records/second\n\n",
6320 6321 6322 6323
          t / 1000.0, superTblInfo->totalInsertRows,
          superTblInfo->totalAffectedRows,
          threads, db_name, superTblInfo->sTblName,
          (double)superTblInfo->totalInsertRows / (t / 1000.0));
6324 6325 6326 6327

    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",
6328 6329 6330 6331
          t / 1000.0, superTblInfo->totalInsertRows,
          superTblInfo->totalAffectedRows,
          threads, db_name, superTblInfo->sTblName,
          (double)superTblInfo->totalInsertRows / (t / 1000.0));
6332
    }
6333
  } else {
6334
    fprintf(stderr, "Spent %.2f seconds to insert rows: %"PRIu64", affected rows: %"PRIu64" with %d thread(s) into %s %.2f records/second\n\n",
6335 6336 6337 6338
          t / 1000.0, g_args.totalInsertRows,
          g_args.totalAffectedRows,
          threads, db_name,
          (double)g_args.totalInsertRows / (t / 1000.0));
6339 6340 6341
    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",
6342 6343 6344 6345
          t * 1000.0, g_args.totalInsertRows,
          g_args.totalAffectedRows,
          threads, db_name,
          (double)g_args.totalInsertRows / (t / 1000.0));
6346
    }
6347
  }
6348

6349
  fprintf(stderr, "insert delay, avg: %10.2fms, max: %"PRIu64"ms, min: %"PRIu64"ms\n\n",
6350
          avgDelay, maxDelay, minDelay);
6351 6352
  if (g_fpOfInsertResult) {
    fprintf(g_fpOfInsertResult, "insert delay, avg:%10.2fms, max: %"PRIu64"ms, min: %"PRIu64"ms\n\n",
6353
          avgDelay, maxDelay, minDelay);
6354
  }
6355

6356 6357
  //taos_close(taos);

H
Hui Li 已提交
6358
  free(pids);
6359
  free(infos);
H
Hui Li 已提交
6360 6361
}

6362
static void *readTable(void *sarg) {
6363
#if 1
6364 6365
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  TAOS *taos = pThreadInfo->taos;
H
hzcheng 已提交
6366
  char command[BUFFER_SIZE] = "\0";
6367 6368 6369
  uint64_t sTime = pThreadInfo->start_time;
  char *tb_prefix = pThreadInfo->tb_prefix;
  FILE *fp = fopen(pThreadInfo->filePath, "a");
H
Hui Li 已提交
6370
  if (NULL == fp) {
6371
    errorPrint( "fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno));
H
Hui Li 已提交
6372 6373
    return NULL;
  }
6374

6375
  int64_t num_of_DPT;
6376 6377
/*  if (pThreadInfo->superTblInfo) {
    num_of_DPT = pThreadInfo->superTblInfo->insertRows; //  nrecords_per_table;
6378
  } else {
6379
  */
6380
      num_of_DPT = g_args.num_of_DPT;
6381
//  }
6382

6383
  int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1;
S
Shuduo Sang 已提交
6384
  int64_t totalData = num_of_DPT * num_of_tables;
6385
  bool do_aggreFunc = g_Dbs.do_aggreFunc;
H
hzcheng 已提交
6386 6387 6388 6389 6390

  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");
  }
S
Shuduo Sang 已提交
6391
  printf("%"PRId64" records:\n", totalData);
H
hzcheng 已提交
6392 6393
  fprintf(fp, "| QFunctions |    QRecords    |   QSpeed(R/s)   |  QLatency(ms) |\n");

6394
  for (int j = 0; j < n; j++) {
H
hzcheng 已提交
6395
    double totalT = 0;
6396
    uint64_t count = 0;
6397 6398
    for (int64_t i = 0; i < num_of_tables; i++) {
      sprintf(command, "select %s from %s%"PRId64" where ts>= %" PRIu64,
6399
              aggreFunc[j], tb_prefix, i, sTime);
H
hzcheng 已提交
6400

6401
      double t = taosGetTimestampMs();
S
Shuaiqiang Chang 已提交
6402 6403
      TAOS_RES *pSql = taos_query(taos, command);
      int32_t code = taos_errno(pSql);
H
hzcheng 已提交
6404

S
Shuaiqiang Chang 已提交
6405
      if (code != 0) {
6406
        errorPrint( "Failed to query:%s\n", taos_errstr(pSql));
S
Shuaiqiang Chang 已提交
6407
        taos_free_result(pSql);
H
hzcheng 已提交
6408
        taos_close(taos);
6409
        fclose(fp);
6410
        return NULL;
H
hzcheng 已提交
6411 6412
      }

6413
      while(taos_fetch_row(pSql) != NULL) {
H
hzcheng 已提交
6414 6415 6416
        count++;
      }

6417
      t = taosGetTimestampMs() - t;
H
hzcheng 已提交
6418 6419
      totalT += t;

S
Shuaiqiang Chang 已提交
6420
      taos_free_result(pSql);
H
hzcheng 已提交
6421 6422
    }

6423
    fprintf(fp, "|%10s  |   %"PRId64"   |  %12.2f   |   %10.2f  |\n",
S
slguan 已提交
6424
            aggreFunc[j][0] == '*' ? "   *   " : aggreFunc[j], totalData,
H
hzcheng 已提交
6425
            (double)(num_of_tables * num_of_DPT) / totalT, totalT * 1000);
6426
    printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT * 1000);
H
hzcheng 已提交
6427 6428 6429
  }
  fprintf(fp, "\n");
  fclose(fp);
6430
#endif
H
hzcheng 已提交
6431 6432 6433
  return NULL;
}

6434
static void *readMetric(void *sarg) {
6435
#if 1
6436 6437
  threadInfo *pThreadInfo = (threadInfo *)sarg;
  TAOS *taos = pThreadInfo->taos;
H
hzcheng 已提交
6438
  char command[BUFFER_SIZE] = "\0";
6439
  FILE *fp = fopen(pThreadInfo->filePath, "a");
H
Hui Li 已提交
6440
  if (NULL == fp) {
6441
    printf("fopen %s fail, reason:%s.\n", pThreadInfo->filePath, strerror(errno));
H
Hui Li 已提交
6442 6443
    return NULL;
  }
6444

6445 6446
  int64_t num_of_DPT = pThreadInfo->superTblInfo->insertRows;
  int64_t num_of_tables = pThreadInfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1;
S
Shuduo Sang 已提交
6447
  int64_t totalData = num_of_DPT * num_of_tables;
6448
  bool do_aggreFunc = g_Dbs.do_aggreFunc;
H
hzcheng 已提交
6449 6450 6451 6452 6453

  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");
  }
S
Shuduo Sang 已提交
6454 6455
  printf("%"PRId64" records:\n", totalData);
  fprintf(fp, "Querying On %"PRId64" records:\n", totalData);
H
hzcheng 已提交
6456 6457

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

6461
    int64_t m = 10 < num_of_tables ? 10 : num_of_tables;
H
hzcheng 已提交
6462

6463
    for (int64_t i = 1; i <= m; i++) {
H
hzcheng 已提交
6464
      if (i == 1) {
6465
        sprintf(tempS, "t1 = %"PRId64"", i);
H
hzcheng 已提交
6466
      } else {
6467
        sprintf(tempS, " or t1 = %"PRId64" ", i);
H
hzcheng 已提交
6468
      }
6469
      strncat(condition, tempS, COND_BUF_LEN - 1);
H
hzcheng 已提交
6470

L
liu0x54 已提交
6471
      sprintf(command, "select %s from meters where %s", aggreFunc[j], condition);
H
hzcheng 已提交
6472 6473 6474 6475

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

6476
      double t = taosGetTimestampMs();
H
hzcheng 已提交
6477

S
Shuaiqiang Chang 已提交
6478 6479 6480 6481
      TAOS_RES *pSql = taos_query(taos, command);
      int32_t code = taos_errno(pSql);

      if (code != 0) {
6482
        errorPrint( "Failed to query:%s\n", taos_errstr(pSql));
S
Shuaiqiang Chang 已提交
6483
        taos_free_result(pSql);
H
hzcheng 已提交
6484
        taos_close(taos);
6485
        fclose(fp);
6486
        return NULL;
H
hzcheng 已提交
6487 6488
      }
      int count = 0;
6489
      while(taos_fetch_row(pSql) != NULL) {
H
hzcheng 已提交
6490 6491
        count++;
      }
6492
      t = taosGetTimestampMs() - t;
H
hzcheng 已提交
6493

6494
      fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n",
6495 6496
              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 已提交
6497

S
Shuaiqiang Chang 已提交
6498
      taos_free_result(pSql);
H
hzcheng 已提交
6499 6500 6501 6502
    }
    fprintf(fp, "\n");
  }
  fclose(fp);
6503
#endif
H
hzcheng 已提交
6504 6505 6506
  return NULL;
}

6507 6508 6509 6510 6511 6512 6513
static void prompt()
{
  if (!g_args.answer_yes) {
    printf("         Press enter key to continue or Ctrl-C to stop\n\n");
    (void)getchar();
  }
}
H
Hui Li 已提交
6514

6515
static int insertTestProcess() {
6516

6517 6518 6519
  setupForAnsiEscape();
  int ret = printfInsertMeta();
  resetAfterAnsiEscape();
6520

6521 6522 6523
  if (ret == -1)
    exit(EXIT_FAILURE);

6524
  debugPrint("%d result file: %s\n", __LINE__, g_Dbs.resultFile);
6525 6526
  g_fpOfInsertResult = fopen(g_Dbs.resultFile, "a");
  if (NULL == g_fpOfInsertResult) {
6527
    errorPrint( "Failed to open %s for save result\n", g_Dbs.resultFile);
6528 6529
    return -1;
  }
6530

6531 6532
  if (g_fpOfInsertResult)
    printfInsertMetaToFile(g_fpOfInsertResult);
6533

6534
  prompt();
6535

6536 6537 6538
  init_rand_data();

  // create database and super tables
6539
  if(createDatabasesAndStables() != 0) {
6540 6541
    if (g_fpOfInsertResult)
      fclose(g_fpOfInsertResult);
6542 6543
    return -1;
  }
6544 6545

  // pretreatement
6546
  prepareSampleData();
6547

6548 6549 6550 6551
  double start;
  double end;

  // create child tables
6552
  start = taosGetTimestampMs();
6553
  createChildTables();
6554
  end = taosGetTimestampMs();
6555

6556
  if (g_totalChildTables > 0) {
6557
    fprintf(stderr, "Spent %.4f seconds to create %"PRId64" tables with %d thread(s)\n\n",
6558
            (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl);
6559 6560
    if (g_fpOfInsertResult) {
      fprintf(g_fpOfInsertResult,
6561
            "Spent %.4f seconds to create %"PRId64" tables with %d thread(s)\n\n",
6562
            (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl);
6563
    }
6564
  }
6565

6566
  taosMsleep(1000);
6567
  // create sub threads for inserting data
6568
  //start = taosGetTimestampMs();
6569
  for (int i = 0; i < g_Dbs.dbCount; i++) {
6570 6571
    if (g_Dbs.use_metric) {
      if (g_Dbs.db[i].superTblCount > 0) {
S
Shuduo Sang 已提交
6572
        for (uint64_t j = 0; j < g_Dbs.db[i].superTblCount; j++) {
6573 6574 6575 6576 6577

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

          if (superTblInfo && (superTblInfo->insertRows > 0)) {
            startMultiThreadInsertData(
6578 6579 6580 6581
              g_Dbs.threadCount,
              g_Dbs.db[i].dbName,
              g_Dbs.db[i].dbCfg.precision,
              superTblInfo);
6582
          }
6583
        }
6584
      }
6585
    } else {
6586
        startMultiThreadInsertData(
6587 6588 6589
          g_Dbs.threadCount,
          g_Dbs.db[i].dbName,
          g_Dbs.db[i].dbCfg.precision,
6590
          NULL);
H
Hui Li 已提交
6591
    }
6592
  }
6593
  //end = taosGetTimestampMs();
6594

6595
  //int64_t    totalInsertRows = 0;
6596
  //int64_t    totalAffectedRows = 0;
6597
  //for (int i = 0; i < g_Dbs.dbCount; i++) {
6598
  //  for (int j = 0; j < g_Dbs.db[i].superTblCount; j++) {
6599
  //  totalInsertRows+= g_Dbs.db[i].superTbls[j].totalInsertRows;
6600 6601
  //  totalAffectedRows += g_Dbs.db[i].superTbls[j].totalAffectedRows;
  //}
6602
  //printf("Spent %.4f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s)\n\n", end - start, totalInsertRows, totalAffectedRows, g_Dbs.threadCount);
6603
  postFreeResource();
6604

6605 6606 6607
  return 0;
}

6608 6609
static void *specifiedTableQuery(void *sarg) {
  threadInfo *pThreadInfo = (threadInfo *)sarg;
6610

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

6627 6628
  char sqlStr[MAX_DB_NAME_SIZE + 5];
  sprintf(sqlStr, "use %s", g_queryInfo.dbName);
6629 6630
  if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
    taos_close(pThreadInfo->taos);
6631 6632 6633 6634
    errorPrint( "use database %s failed!\n\n",
                g_queryInfo.dbName);
    return NULL;
  }
6635

6636 6637
  uint64_t st = 0;
  uint64_t et = 0;
6638

6639
  uint64_t queryTimes = g_queryInfo.specifiedQueryInfo.queryTimes;
6640

6641 6642 6643
  uint64_t totalQueried = 0;
  uint64_t lastPrintTime = taosGetTimestampMs();
  uint64_t startTs = taosGetTimestampMs();
6644

6645
  if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') {
6646
    sprintf(pThreadInfo->filePath, "%s-%d",
6647 6648 6649 6650
                g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
                pThreadInfo->threadID);
  }

6651
  while(queryTimes --) {
6652
    if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) <
6653
            (int64_t)g_queryInfo.specifiedQueryInfo.queryInterval) {
6654
      taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval - (et - st)); // ms
6655 6656
    }

6657 6658 6659
    st = taosGetTimestampMs();

    selectAndGetResult(pThreadInfo,
6660
          g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq]);
6661

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

6666 6667
    totalQueried ++;
    g_queryInfo.specifiedQueryInfo.totalQueried ++;
6668

6669 6670
    uint64_t  currentPrintTime = taosGetTimestampMs();
    uint64_t  endTs = taosGetTimestampMs();
6671
    if (currentPrintTime - lastPrintTime > 30*1000) {
6672
      debugPrint("%s() LN%d, endTs=%"PRIu64"ms, startTs=%"PRIu64"ms\n",
6673
          __func__, __LINE__, endTs, startTs);
6674
      printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.6f\n",
6675 6676
                    pThreadInfo->threadID,
                    totalQueried,
6677
                    (double)(totalQueried/((endTs-startTs)/1000.0)));
6678
      lastPrintTime = currentPrintTime;
6679
    }
H
Hui Li 已提交
6680
  }
6681 6682
  return NULL;
}
H
Hui Li 已提交
6683

6684
static void replaceChildTblName(char* inSql, char* outSql, int tblIndex) {
6685 6686
  char sourceString[32] = "xxxx";
  char subTblName[MAX_TB_NAME_SIZE*3];
6687 6688
  sprintf(subTblName, "%s.%s",
          g_queryInfo.dbName,
6689
          g_queryInfo.superQueryInfo.childTblName + tblIndex*TSDB_TABLE_NAME_LEN);
6690 6691

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

6693 6694
  char* pos = strstr(inSql, sourceString);
  if (0 == pos) {
6695
    return;
H
Hui Li 已提交
6696
  }
6697

6698
  tstrncpy(outSql, inSql, pos - inSql + 1);
6699
  //printf("1: %s\n", outSql);
6700
  strncat(outSql, subTblName, MAX_QUERY_SQL_LENGTH - 1);
6701
  //printf("2: %s\n", outSql);
6702
  strncat(outSql, pos+strlen(sourceString), MAX_QUERY_SQL_LENGTH - 1);
6703
  //printf("3: %s\n", outSql);
H
Hui Li 已提交
6704 6705
}

6706
static void *superTableQuery(void *sarg) {
6707
  char sqlstr[MAX_QUERY_SQL_LENGTH];
6708
  threadInfo *pThreadInfo = (threadInfo *)sarg;
6709

6710
  if (pThreadInfo->taos == NULL) {
6711 6712 6713 6714 6715 6716 6717 6718
    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",
6719
            pThreadInfo->threadID, taos_errstr(NULL));
6720 6721
      return NULL;
    } else {
6722
      pThreadInfo->taos = taos;
6723 6724 6725
    }
  }

6726 6727
  uint64_t st = 0;
  uint64_t et = (int64_t)g_queryInfo.superQueryInfo.queryInterval;
6728

6729 6730 6731
  uint64_t queryTimes = g_queryInfo.superQueryInfo.queryTimes;
  uint64_t totalQueried = 0;
  uint64_t  startTs = taosGetTimestampMs();
6732

6733
  uint64_t  lastPrintTime = taosGetTimestampMs();
6734
  while(queryTimes --) {
6735 6736 6737
    if (g_queryInfo.superQueryInfo.queryInterval
            && (et - st) < (int64_t)g_queryInfo.superQueryInfo.queryInterval) {
      taosMsleep(g_queryInfo.superQueryInfo.queryInterval - (et - st)); // ms
6738
      //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to);
6739
    }
H
Hui Li 已提交
6740

6741
    st = taosGetTimestampMs();
6742
    for (int i = pThreadInfo->start_table_from; i <= pThreadInfo->end_table_to; i++) {
6743
      for (int j = 0; j < g_queryInfo.superQueryInfo.sqlCount; j++) {
6744
        memset(sqlstr,0,sizeof(sqlstr));
6745
        replaceChildTblName(g_queryInfo.superQueryInfo.sql[j], sqlstr, i);
6746
        if (g_queryInfo.superQueryInfo.result[j][0] != '\0') {
6747
          sprintf(pThreadInfo->filePath, "%s-%d",
6748
                  g_queryInfo.superQueryInfo.result[j],
6749
                  pThreadInfo->threadID);
6750
        }
6751
        selectAndGetResult(pThreadInfo, sqlstr);
6752 6753 6754 6755 6756 6757 6758

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

        int64_t  currentPrintTime = taosGetTimestampMs();
        int64_t  endTs = taosGetTimestampMs();
        if (currentPrintTime - lastPrintTime > 30*1000) {
6759
          printf("thread[%d] has currently completed queries: %"PRIu64", QPS: %10.3f\n",
6760 6761
                    pThreadInfo->threadID,
                    totalQueried,
6762
                    (double)(totalQueried/((endTs-startTs)/1000.0)));
6763
          lastPrintTime = currentPrintTime;
6764
        }
6765
      }
H
Hui Li 已提交
6766
    }
6767
    et = taosGetTimestampMs();
6768
    printf("####thread[%"PRId64"] complete all sqls to allocate all sub-tables[%"PRIu64" - %"PRIu64"] once queries duration:%.4fs\n\n",
6769
            taosGetSelfPthreadId(),
6770 6771
            pThreadInfo->start_table_from,
            pThreadInfo->end_table_to,
6772
            (double)(et - st)/1000.0);
6773
  }
6774

6775 6776 6777
  return NULL;
}

6778
static int queryTestProcess() {
6779 6780 6781 6782

  setupForAnsiEscape();
  printfQueryMeta();
  resetAfterAnsiEscape();
6783 6784 6785 6786 6787 6788

  TAOS * taos = NULL;
  taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          NULL,
6789
          g_queryInfo.port);
6790
  if (taos == NULL) {
6791 6792
    errorPrint( "Failed to connect to TDengine, reason:%s\n",
            taos_errstr(NULL));
6793 6794 6795
    exit(-1);
  }

6796
  if (0 != g_queryInfo.superQueryInfo.sqlCount) {
6797 6798
    getAllChildNameOfSuperTable(taos,
            g_queryInfo.dbName,
6799 6800 6801
            g_queryInfo.superQueryInfo.sTblName,
            &g_queryInfo.superQueryInfo.childTblName,
            &g_queryInfo.superQueryInfo.childTblCount);
6802
  }
6803

6804
  prompt();
6805

6806 6807 6808
  if (g_args.debug_print || g_args.verbose_print) {
    printfQuerySystemInfo(taos);
  }
6809

6810 6811 6812 6813 6814 6815
  if (0 == strncasecmp(g_queryInfo.queryMode, "rest", strlen("rest"))) {
    if (convertHostToServAddr(
        g_queryInfo.host, g_queryInfo.port, &g_queryInfo.serv_addr) != 0)
      exit(-1);
  }

6816 6817 6818
  pthread_t  *pids  = NULL;
  threadInfo *infos = NULL;
  //==== create sub threads for query from specify table
6819
  int nConcurrent = g_queryInfo.specifiedQueryInfo.concurrent;
6820
  uint64_t nSqlCount = g_queryInfo.specifiedQueryInfo.sqlCount;
6821

6822
  uint64_t startTs = taosGetTimestampMs();
6823

6824 6825 6826 6827 6828 6829
  if ((nSqlCount > 0) && (nConcurrent > 0)) {

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

    if ((NULL == pids) || (NULL == infos)) {
6830
      taos_close(taos);
6831
      ERROR_EXIT("memory allocation failed for create threads\n");
6832
    }
6833

6834 6835 6836
    for (uint64_t i = 0; i < nSqlCount; i++) {
        for (int j = 0; j < nConcurrent; j++) {
            uint64_t seq = i * nConcurrent + j;
6837 6838 6839
            threadInfo *pThreadInfo = infos + seq;
            pThreadInfo->threadID = seq;
            pThreadInfo->querySeq = i;
6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853

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

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

6855
            pThreadInfo->taos = NULL;// TODO: workaround to use separate taos connection;
6856

6857
            pthread_create(pids + seq, NULL, specifiedTableQuery,
6858
                pThreadInfo);
6859
        }
6860
    }
6861
  } else {
6862
    g_queryInfo.specifiedQueryInfo.concurrent = 0;
6863
  }
6864

6865 6866
  taos_close(taos);

6867 6868 6869
  pthread_t  *pidsOfSub  = NULL;
  threadInfo *infosOfSub = NULL;
  //==== create sub threads for query from all sub table of the super table
6870 6871 6872 6873
  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));
6874 6875

    if ((NULL == pidsOfSub) || (NULL == infosOfSub)) {
6876 6877
      free(infos);
      free(pids);
6878

6879
      ERROR_EXIT("memory allocation failed for create threads\n");
6880
    }
6881

S
Shuduo Sang 已提交
6882
    int64_t ntables = g_queryInfo.superQueryInfo.childTblCount;
6883
    int threads = g_queryInfo.superQueryInfo.threadCnt;
6884

S
Shuduo Sang 已提交
6885
    int64_t a = ntables / threads;
6886 6887 6888 6889
    if (a < 1) {
      threads = ntables;
      a = 1;
    }
6890

S
Shuduo Sang 已提交
6891
    int64_t b = 0;
6892 6893 6894
    if (threads != 0) {
      b = ntables % threads;
    }
6895

6896
    uint64_t tableFrom = 0;
6897
    for (int i = 0; i < threads; i++) {
6898 6899
      threadInfo *pThreadInfo = infosOfSub + i;
      pThreadInfo->threadID = i;
6900

6901
      pThreadInfo->start_table_from = tableFrom;
6902
      pThreadInfo->ntables = i<b?a+1:a;
6903 6904
      pThreadInfo->end_table_to = i < b ? tableFrom + a : tableFrom + a - 1;
      tableFrom = pThreadInfo->end_table_to + 1;
6905 6906
      pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection;
      pthread_create(pidsOfSub + i, NULL, superTableQuery, pThreadInfo);
6907 6908
    }

6909
    g_queryInfo.superQueryInfo.threadCnt = threads;
6910
  } else {
6911
    g_queryInfo.superQueryInfo.threadCnt = 0;
6912
  }
6913

6914 6915 6916 6917 6918 6919
  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);
      }
    }
6920
  }
S
Shuaiqiang Chang 已提交
6921

6922
  tmfree((char*)pids);
6923
  tmfree((char*)infos);
6924

6925
  for (int i = 0; i < g_queryInfo.superQueryInfo.threadCnt; i++) {
6926
    pthread_join(pidsOfSub[i], NULL);
H
hzcheng 已提交
6927
  }
H
Hui Li 已提交
6928

6929
  tmfree((char*)pidsOfSub);
6930
  tmfree((char*)infosOfSub);
6931

6932
//  taos_close(taos);// TODO: workaround to use separate taos connection;
6933
  uint64_t endTs = taosGetTimestampMs();
6934

6935
  uint64_t totalQueried = g_queryInfo.specifiedQueryInfo.totalQueried +
6936 6937
    g_queryInfo.superQueryInfo.totalQueried;

6938
  fprintf(stderr, "==== completed total queries: %"PRIu64", the QPS of all threads: %10.3f====\n",
6939
          totalQueried,
6940
          (double)(totalQueried/((endTs-startTs)/1000.0)));
6941 6942 6943
  return 0;
}

6944 6945 6946 6947 6948 6949 6950 6951 6952
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)
6953
    fetchResult(res, (threadInfo *)param);
6954 6955 6956 6957 6958
  // tao_unscribe() will free result.
}

static void specified_sub_callback(
        TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
6959
  if (res == NULL || taos_errno(res) != 0) {
6960 6961
    errorPrint("%s() LN%d, failed to subscribe result, code:%d, reason:%s\n",
           __func__, __LINE__, code, taos_errstr(res));
6962 6963
    return;
  }
6964

6965
  if (param)
6966
    fetchResult(res, (threadInfo *)param);
6967
  // tao_unscribe() will free result.
H
hzcheng 已提交
6968 6969
}

6970
static TAOS_SUB* subscribeImpl(
6971 6972 6973 6974
        QUERY_CLASS class,
        threadInfo *pThreadInfo,
        char *sql, char* topic, bool restart, uint64_t interval)
{
6975
  TAOS_SUB* tsub = NULL;
H
hzcheng 已提交
6976

6977 6978 6979 6980
  if ((SPECIFIED_CLASS == class)
          && (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode)) {
    tsub = taos_subscribe(
            pThreadInfo->taos,
6981
            restart,
6982
            topic, sql, specified_sub_callback, (void*)pThreadInfo,
6983
            g_queryInfo.specifiedQueryInfo.subscribeInterval);
6984 6985 6986 6987 6988 6989 6990
  } else if ((STABLE_CLASS == class)
          && (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode)) {
    tsub = taos_subscribe(
            pThreadInfo->taos,
            restart,
            topic, sql, stable_sub_callback, (void*)pThreadInfo,
            g_queryInfo.superQueryInfo.subscribeInterval);
6991
  } else {
6992 6993
    tsub = taos_subscribe(
            pThreadInfo->taos,
6994
            restart,
6995
            topic, sql, NULL, NULL, interval);
6996
  }
6997

6998 6999 7000
  if (tsub == NULL) {
    printf("failed to create subscription. topic:%s, sql:%s\n", topic, sql);
    return NULL;
7001
  }
7002

7003 7004
  return tsub;
}
H
hzcheng 已提交
7005

7006 7007
static void *superSubscribe(void *sarg) {
  threadInfo *pThreadInfo = (threadInfo *)sarg;
7008
  char subSqlstr[MAX_QUERY_SQL_LENGTH];
7009
  TAOS_SUB*    tsub[MAX_QUERY_SQL_COUNT] = {0};
7010
  uint64_t tsubSeq;
H
hzcheng 已提交
7011

7012 7013
  if (pThreadInfo->ntables > MAX_QUERY_SQL_COUNT) {
      errorPrint("The table number(%"PRId64") of the thread is more than max query sql count: %d\n",
7014 7015 7016 7017 7018
              pThreadInfo->ntables,
              MAX_QUERY_SQL_COUNT);
      exit(-1);
  }

7019
  if (pThreadInfo->taos == NULL) {
7020
    pThreadInfo->taos = taos_connect(g_queryInfo.host,
7021 7022 7023 7024
          g_queryInfo.user,
          g_queryInfo.password,
          g_queryInfo.dbName,
          g_queryInfo.port);
7025
    if (pThreadInfo->taos == NULL) {
7026
      errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
7027
            pThreadInfo->threadID, taos_errstr(NULL));
7028 7029 7030 7031
      return NULL;
    }
  }

7032 7033
  char sqlStr[MAX_TB_NAME_SIZE*2];
  sprintf(sqlStr, "use %s", g_queryInfo.dbName);
7034 7035
  if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
    taos_close(pThreadInfo->taos);
7036 7037
    errorPrint( "use database %s failed!\n\n",
                g_queryInfo.dbName);
7038 7039
    return NULL;
  }
7040

S
Shengliang Guan 已提交
7041 7042 7043
  char topic[32] = {0};
  for (uint64_t i = pThreadInfo->start_table_from;
          i <= pThreadInfo->end_table_to; i++) {
7044 7045

      tsubSeq = i - pThreadInfo->start_table_from;
7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057
      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);
      sprintf(topic, "taosdemo-subscribe-%"PRIu64"-%"PRIu64"",
              i, pThreadInfo->querySeq);
      memset(subSqlstr, 0, sizeof(subSqlstr));
      replaceChildTblName(
              g_queryInfo.superQueryInfo.sql[pThreadInfo->querySeq],
              subSqlstr, i);
      if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
7058
        sprintf(pThreadInfo->filePath, "%s-%d",
7059 7060 7061 7062 7063 7064
                g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq],
                pThreadInfo->threadID);
      }

      debugPrint("%s() LN%d, [%d] subSqlstr: %s\n",
              __func__, __LINE__, pThreadInfo->threadID, subSqlstr);
7065
      tsub[tsubSeq] = subscribeImpl(
7066 7067 7068 7069
              STABLE_CLASS,
              pThreadInfo, subSqlstr, topic,
              g_queryInfo.superQueryInfo.subscribeRestart,
              g_queryInfo.superQueryInfo.subscribeInterval);
7070
      if (NULL == tsub[tsubSeq]) {
7071
        taos_close(pThreadInfo->taos);
7072 7073
        return NULL;
      }
S
Shengliang Guan 已提交
7074
  }
7075 7076

  // start loop to consume result
7077 7078 7079 7080
  int consumed[MAX_QUERY_SQL_COUNT];
  for (int i = 0; i < MAX_QUERY_SQL_COUNT; i++) {
    consumed[i] = 0;
  }
7081
  TAOS_RES* res = NULL;
7082

7083 7084
  uint64_t st = 0, et = 0;

7085
  while(1) {
7086 7087
    for (uint64_t i = pThreadInfo->start_table_from;
            i <= pThreadInfo->end_table_to; i++) {
7088 7089 7090 7091
      tsubSeq = i - pThreadInfo->start_table_from;
      if (ASYNC_MODE == g_queryInfo.superQueryInfo.asyncMode) {
          continue;
      }
7092

7093 7094
      st = taosGetTimestampMs();
      performancePrint("st: %"PRIu64" et: %"PRIu64" st-et: %"PRIu64"\n", st, et, (st - et));
7095
      res = taos_consume(tsub[tsubSeq]);
7096 7097 7098
      et = taosGetTimestampMs();
      performancePrint("st: %"PRIu64" et: %"PRIu64" delta: %"PRIu64"\n", st, et, (et - st));

7099 7100
      if (res) {
          if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
7101
              sprintf(pThreadInfo->filePath, "%s-%d",
7102 7103
                      g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq],
                      pThreadInfo->threadID);
7104
              fetchResult(res, pThreadInfo);
7105 7106
          }
          if (g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
7107
              sprintf(pThreadInfo->filePath, "%s-%d",
7108 7109
                      g_queryInfo.superQueryInfo.result[pThreadInfo->querySeq],
                      pThreadInfo->threadID);
7110
              fetchResult(res, pThreadInfo);
7111 7112 7113 7114 7115
          }
          consumed[tsubSeq] ++;

          if ((g_queryInfo.superQueryInfo.subscribeKeepProgress)
                  && (consumed[tsubSeq] >=
7116
                      g_queryInfo.superQueryInfo.resubAfterConsume)) {
7117 7118 7119 7120
              printf("keepProgress:%d, resub super table query: %"PRIu64"\n",
                      g_queryInfo.superQueryInfo.subscribeKeepProgress,
                      pThreadInfo->querySeq);
              taos_unsubscribe(tsub[tsubSeq],
7121
                    g_queryInfo.superQueryInfo.subscribeKeepProgress);
7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134
              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 已提交
7135 7136
    }
  }
7137
  taos_free_result(res);
7138

S
Shengliang Guan 已提交
7139 7140
  for (uint64_t i = pThreadInfo->start_table_from;
          i <= pThreadInfo->end_table_to; i++) {
7141 7142
    tsubSeq = i - pThreadInfo->start_table_from;
    taos_unsubscribe(tsub[tsubSeq], 0);
7143
  }
7144

7145
  taos_close(pThreadInfo->taos);
H
hzcheng 已提交
7146 7147 7148
  return NULL;
}

7149 7150
static void *specifiedSubscribe(void *sarg) {
  threadInfo *pThreadInfo = (threadInfo *)sarg;
7151
//  TAOS_SUB*  tsub = NULL;
7152

7153
  if (pThreadInfo->taos == NULL) {
7154
    pThreadInfo->taos = taos_connect(g_queryInfo.host,
7155 7156 7157 7158
          g_queryInfo.user,
          g_queryInfo.password,
          g_queryInfo.dbName,
          g_queryInfo.port);
7159
    if (pThreadInfo->taos == NULL) {
7160
      errorPrint("[%d] Failed to connect to TDengine, reason:%s\n",
7161
            pThreadInfo->threadID, taos_errstr(NULL));
7162 7163 7164 7165
      return NULL;
    }
  }

7166 7167
  char sqlStr[MAX_TB_NAME_SIZE*2];
  sprintf(sqlStr, "use %s", g_queryInfo.dbName);
7168 7169
  if (0 != queryDbExec(pThreadInfo->taos, sqlStr, NO_INSERT_TYPE, false)) {
    taos_close(pThreadInfo->taos);
7170 7171
    return NULL;
  }
7172

7173 7174 7175 7176
  sprintf(g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID],
          "taosdemo-subscribe-%"PRIu64"-%d",
          pThreadInfo->querySeq,
          pThreadInfo->threadID);
7177
  if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != '\0') {
7178
      sprintf(pThreadInfo->filePath, "%s-%d",
7179 7180 7181
                g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
                pThreadInfo->threadID);
  }
7182 7183
  g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] = subscribeImpl(
          SPECIFIED_CLASS, pThreadInfo,
7184
          g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
7185
          g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID],
7186
          g_queryInfo.specifiedQueryInfo.subscribeRestart,
7187
          g_queryInfo.specifiedQueryInfo.subscribeInterval);
7188
  if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) {
7189 7190
      taos_close(pThreadInfo->taos);
      return NULL;
S
Shengliang Guan 已提交
7191
  }
7192

7193
  // start loop to consume result
7194

7195
  g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
7196
  while(1) {
7197
      if (ASYNC_MODE == g_queryInfo.specifiedQueryInfo.asyncMode) {
7198 7199
        continue;
      }
7200

7201 7202 7203
      g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID] = taos_consume(
              g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]);
      if (g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]) {
7204
          if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) {
7205
              sprintf(pThreadInfo->filePath, "%s-%d",
7206 7207
                      g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq],
                      pThreadInfo->threadID);
7208
              fetchResult(g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID], pThreadInfo);
7209 7210
          }

7211
          g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] ++;
7212
          if ((g_queryInfo.specifiedQueryInfo.subscribeKeepProgress)
7213
                && (g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] >=
7214 7215 7216 7217
                    g_queryInfo.specifiedQueryInfo.resubAfterConsume[pThreadInfo->querySeq])) {
              printf("keepProgress:%d, resub specified query: %"PRIu64"\n",
                    g_queryInfo.specifiedQueryInfo.subscribeKeepProgress,
                    pThreadInfo->querySeq);
7218 7219
              g_queryInfo.specifiedQueryInfo.consumed[pThreadInfo->threadID] = 0;
              taos_unsubscribe(g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID],
7220
                      g_queryInfo.specifiedQueryInfo.subscribeKeepProgress);
7221
              g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID] = subscribeImpl(
7222 7223 7224
                      SPECIFIED_CLASS,
                      pThreadInfo,
                      g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq],
7225
                      g_queryInfo.specifiedQueryInfo.topic[pThreadInfo->threadID],
7226 7227
                      g_queryInfo.specifiedQueryInfo.subscribeRestart,
                      g_queryInfo.specifiedQueryInfo.subscribeInterval);
7228
              if (NULL == g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->threadID]) {
7229 7230
                taos_close(pThreadInfo->taos);
                return NULL;
7231 7232
              }
          }
7233 7234
      }
  }
7235 7236
  taos_free_result(g_queryInfo.specifiedQueryInfo.res[pThreadInfo->threadID]);
  taos_unsubscribe(g_queryInfo.specifiedQueryInfo.tsub[pThreadInfo->querySeq], 0);
7237
  taos_close(pThreadInfo->taos);
7238

H
hzcheng 已提交
7239 7240 7241
  return NULL;
}

7242
static int subscribeTestProcess() {
7243
  setupForAnsiEscape();
7244
  printfQueryMeta();
7245
  resetAfterAnsiEscape();
7246

7247
  prompt();
7248

7249 7250 7251 7252 7253
  TAOS * taos = NULL;
  taos = taos_connect(g_queryInfo.host,
          g_queryInfo.user,
          g_queryInfo.password,
          g_queryInfo.dbName,
7254
          g_queryInfo.port);
7255
  if (taos == NULL) {
7256 7257
    errorPrint( "Failed to connect to TDengine, reason:%s\n",
            taos_errstr(NULL));
7258 7259 7260
    exit(-1);
  }

7261
  if (0 != g_queryInfo.superQueryInfo.sqlCount) {
7262 7263
    getAllChildNameOfSuperTable(taos,
            g_queryInfo.dbName,
7264 7265 7266
            g_queryInfo.superQueryInfo.sTblName,
            &g_queryInfo.superQueryInfo.childTblName,
            &g_queryInfo.superQueryInfo.childTblCount);
7267 7268
  }

7269 7270
  taos_close(taos); // TODO: workaround to use separate taos connection;

7271 7272
  pthread_t  *pids = NULL;
  threadInfo *infos = NULL;
7273 7274 7275 7276 7277

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

  //==== create threads for query for specified table
S
Shengliang Guan 已提交
7278
  if (g_queryInfo.specifiedQueryInfo.sqlCount <= 0) {
7279
    debugPrint("%s() LN%d, sepcified query sqlCount %"PRIu64".\n",
7280
              __func__, __LINE__,
S
Shengliang Guan 已提交
7281 7282 7283 7284 7285 7286 7287 7288
              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);
    }
7289

7290 7291 7292 7293 7294 7295 7296 7297
    pids  = malloc(
            g_queryInfo.specifiedQueryInfo.sqlCount *
            g_queryInfo.specifiedQueryInfo.concurrent *
            sizeof(pthread_t));
    infos = malloc(
            g_queryInfo.specifiedQueryInfo.sqlCount *
            g_queryInfo.specifiedQueryInfo.concurrent *
            sizeof(threadInfo));
S
Shengliang Guan 已提交
7298 7299 7300 7301
    if ((NULL == pids) || (NULL == infos)) {
        errorPrint("%s() LN%d, malloc failed for create threads\n", __func__, __LINE__);
        exit(-1);
    }
7302

7303 7304 7305
    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;
7306 7307 7308 7309 7310
            threadInfo *pThreadInfo = infos + seq;
            pThreadInfo->threadID = seq;
            pThreadInfo->querySeq = i;
            pThreadInfo->taos = NULL;  // TODO: workaround to use separate taos connection;
            pthread_create(pids + seq, NULL, specifiedSubscribe, pThreadInfo);
7311
        }
S
Shengliang Guan 已提交
7312
    }
H
hzcheng 已提交
7313
  }
7314

7315 7316
  //==== create threads for super table query
  if (g_queryInfo.superQueryInfo.sqlCount <= 0) {
7317
    debugPrint("%s() LN%d, super table query sqlCount %"PRIu64".\n",
7318 7319 7320 7321
              __func__, __LINE__,
              g_queryInfo.superQueryInfo.sqlCount);
  } else {
    if ((g_queryInfo.superQueryInfo.sqlCount > 0)
7322
          && (g_queryInfo.superQueryInfo.threadCnt > 0)) {
7323 7324 7325
        pidsOfStable  = malloc(
                g_queryInfo.superQueryInfo.sqlCount *
                g_queryInfo.superQueryInfo.threadCnt *
7326
            sizeof(pthread_t));
7327 7328 7329
        infosOfStable = malloc(
                g_queryInfo.superQueryInfo.sqlCount *
                g_queryInfo.superQueryInfo.threadCnt *
7330
            sizeof(threadInfo));
7331 7332
        if ((NULL == pidsOfStable) || (NULL == infosOfStable)) {
            errorPrint("%s() LN%d, malloc failed for create threads\n",
7333
              __func__, __LINE__);
7334 7335 7336
            // taos_close(taos);
            exit(-1);
        }
7337

7338 7339
        int64_t ntables = g_queryInfo.superQueryInfo.childTblCount;
        int threads = g_queryInfo.superQueryInfo.threadCnt;
7340

7341 7342 7343 7344 7345
        int64_t a = ntables / threads;
        if (a < 1) {
            threads = ntables;
            a = 1;
        }
7346

7347 7348 7349 7350
        int64_t b = 0;
        if (threads != 0) {
            b = ntables % threads;
        }
7351

7352
        for (uint64_t i = 0; i < g_queryInfo.superQueryInfo.sqlCount; i++) {
7353
            uint64_t tableFrom = 0;
7354 7355
            for (int j = 0; j < threads; j++) {
                uint64_t seq = i * threads + j;
7356 7357 7358 7359
                threadInfo *pThreadInfo = infosOfStable + seq;
                pThreadInfo->threadID = seq;
                pThreadInfo->querySeq = i;

7360
                pThreadInfo->start_table_from = tableFrom;
7361
                pThreadInfo->ntables = j<b?a+1:a;
7362 7363
                pThreadInfo->end_table_to = j<b?tableFrom+a:tableFrom+a-1;
                tableFrom = pThreadInfo->end_table_to + 1;
7364
                pThreadInfo->taos = NULL; // TODO: workaround to use separate taos connection;
7365
                pthread_create(pidsOfStable + seq,
7366
                        NULL, superSubscribe, pThreadInfo);
7367 7368
            }
        }
7369

7370
        g_queryInfo.superQueryInfo.threadCnt = threads;
7371

7372 7373 7374 7375 7376 7377
        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);
            }
        }
7378
    }
H
hzcheng 已提交
7379
  }
7380

7381 7382 7383 7384 7385
  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);
    }
7386
  }
H
hzcheng 已提交
7387

7388
  tmfree((char*)pids);
7389
  tmfree((char*)infos);
H
hzcheng 已提交
7390

7391 7392
  tmfree((char*)pidsOfStable);
  tmfree((char*)infosOfStable);
7393
//   taos_close(taos);
7394
  return 0;
H
hzcheng 已提交
7395 7396
}

7397
static void initOfInsertMeta() {
7398
  memset(&g_Dbs, 0, sizeof(SDbs));
7399

7400
  // set default values
7401
  tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
7402
  g_Dbs.port = 6030;
7403 7404
  tstrncpy(g_Dbs.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE);
  tstrncpy(g_Dbs.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE);
7405
  g_Dbs.threadCount = 2;
7406 7407

  g_Dbs.use_metric = g_args.use_metric;
L
Liu Tao 已提交
7408 7409
}

7410
static void initOfQueryMeta() {
7411
  memset(&g_queryInfo, 0, sizeof(SQueryMetaInfo));
7412

7413
  // set default values
7414
  tstrncpy(g_queryInfo.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
7415
  g_queryInfo.port = 6030;
7416 7417
  tstrncpy(g_queryInfo.user, TSDB_DEFAULT_USER, MAX_USERNAME_SIZE);
  tstrncpy(g_queryInfo.password, TSDB_DEFAULT_PASS, MAX_PASSWORD_SIZE);
L
Liu Tao 已提交
7418 7419
}

7420
static void setParaFromArg(){
7421
  if (g_args.host) {
7422
    tstrncpy(g_Dbs.host, g_args.host, MAX_HOSTNAME_SIZE);
7423
  } else {
7424
    tstrncpy(g_Dbs.host, "127.0.0.1", MAX_HOSTNAME_SIZE);
7425
  }
L
Liu Tao 已提交
7426

7427
  if (g_args.user) {
7428
    tstrncpy(g_Dbs.user, g_args.user, MAX_USERNAME_SIZE);
7429
  }
7430 7431

  if (g_args.password) {
7432
    tstrncpy(g_Dbs.password, g_args.password, MAX_PASSWORD_SIZE);
7433 7434
  }

7435 7436
  if (g_args.port) {
    g_Dbs.port = g_args.port;
7437
  }
L
Liu Tao 已提交
7438

7439 7440 7441
  g_Dbs.threadCount = g_args.num_of_threads;
  g_Dbs.threadCountByCreateTbl = g_args.num_of_threads;

7442 7443
  g_Dbs.dbCount = 1;
  g_Dbs.db[0].drop = 1;
7444

7445
  tstrncpy(g_Dbs.db[0].dbName, g_args.database, MAX_DB_NAME_SIZE);
7446
  g_Dbs.db[0].dbCfg.replica = g_args.replica;
7447
  tstrncpy(g_Dbs.db[0].dbCfg.precision, "ms", MAX_DB_NAME_SIZE);
L
Liu Tao 已提交
7448

7449
  tstrncpy(g_Dbs.resultFile, g_args.output_file, MAX_FILE_NAME_LEN);
7450 7451 7452 7453 7454

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

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

7456 7457
  char dataString[STRING_LEN];
  char **data_type = g_args.datatype;
7458

7459
  memset(dataString, 0, STRING_LEN);
L
Liu Tao 已提交
7460

7461 7462
  if (strcasecmp(data_type[0], "BINARY") == 0
          || strcasecmp(data_type[0], "BOOL") == 0
7463
          || strcasecmp(data_type[0], "NCHAR") == 0 ) {
7464
    g_Dbs.do_aggreFunc = false;
L
Liu Tao 已提交
7465
  }
H
hzcheng 已提交
7466

7467 7468 7469 7470 7471
  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;
7472
    g_Dbs.threadCountByCreateTbl = g_args.num_of_threads;
7473
    g_Dbs.asyncMode = g_args.async_mode;
7474

7475 7476 7477 7478
    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;
7479
    tstrncpy(g_Dbs.db[0].superTbls[0].childTblPrefix,
7480 7481
            g_args.tb_prefix, MAX_TB_NAME_SIZE);
    tstrncpy(g_Dbs.db[0].superTbls[0].dataSource, "rand", MAX_TB_NAME_SIZE);
7482
    g_Dbs.db[0].superTbls[0].iface = g_args.iface;
7483
    tstrncpy(g_Dbs.db[0].superTbls[0].startTimestamp,
7484
            "2017-07-14 10:40:00.000", MAX_TB_NAME_SIZE);
7485
    g_Dbs.db[0].superTbls[0].timeStampStep = DEFAULT_TIMESTAMP_STEP;
7486

7487
    g_Dbs.db[0].superTbls[0].insertRows = g_args.num_of_DPT;
7488
    g_Dbs.db[0].superTbls[0].maxSqlLen = g_args.max_sql_len;
7489

7490 7491 7492 7493 7494
    g_Dbs.db[0].superTbls[0].columnCount = 0;
    for (int i = 0; i < MAX_NUM_DATATYPE; i++) {
      if (data_type[i] == NULL) {
        break;
      }
7495

7496
      tstrncpy(g_Dbs.db[0].superTbls[0].columns[i].dataType,
7497
              data_type[i], MAX_TB_NAME_SIZE);
7498
      g_Dbs.db[0].superTbls[0].columns[i].dataLen = g_args.len_of_binary;
7499 7500
      g_Dbs.db[0].superTbls[0].columnCount++;
    }
7501

7502 7503 7504
    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 {
7505 7506 7507 7508
      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);
7509
        g_Dbs.db[0].superTbls[0].columns[i].dataLen = 0;
7510 7511 7512
        g_Dbs.db[0].superTbls[0].columnCount++;
      }
    }
7513

7514 7515
    tstrncpy(g_Dbs.db[0].superTbls[0].tags[0].dataType,
            "INT", MAX_TB_NAME_SIZE);
7516
    g_Dbs.db[0].superTbls[0].tags[0].dataLen = 0;
7517

7518 7519
    tstrncpy(g_Dbs.db[0].superTbls[0].tags[1].dataType,
            "BINARY", MAX_TB_NAME_SIZE);
7520 7521
    g_Dbs.db[0].superTbls[0].tags[1].dataLen = g_args.len_of_binary;
    g_Dbs.db[0].superTbls[0].tagCount = 2;
7522
  } else {
7523 7524
    g_Dbs.threadCountByCreateTbl = g_args.num_of_threads;
    g_Dbs.db[0].superTbls[0].tagCount = 0;
H
hzcheng 已提交
7525
  }
7526 7527 7528 7529 7530 7531
}

/* 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 已提交
7532

7533 7534 7535
  /* Compile regular expression */
  if (regcomp(&regex, reg, cflags) != 0) {
    printf("Fail to compile regex\n");
H
Hui Li 已提交
7536 7537 7538
    exit(-1);
  }

7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562
  /* 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);
}

7563
static void querySqlFile(TAOS* taos, char* sqlFile)
7564 7565 7566 7567 7568 7569
{
  FILE *fp = fopen(sqlFile, "r");
  if (fp == NULL) {
    printf("failed to open file %s, reason:%s\n", sqlFile, strerror(errno));
    return;
  }
7570

7571 7572 7573 7574 7575 7576
  int       read_len = 0;
  char *    cmd = calloc(1, MAX_SQL_SIZE);
  size_t    cmd_len = 0;
  char *    line = NULL;
  size_t    line_len = 0;

7577
  double t = taosGetTimestampMs();
7578

7579
  while((read_len = tgetline(&line, &line_len, fp)) != -1) {
7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591
    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;
7592
    }
7593 7594

    memcpy(cmd + cmd_len, line, read_len);
7595 7596 7597
    if (0 != queryDbExec(taos, cmd, NO_INSERT_TYPE, false)) {
        errorPrint("%s() LN%d, queryDbExec %s failed!\n",
               __func__, __LINE__, cmd);
7598 7599 7600 7601 7602
        tmfree(cmd);
        tmfree(line);
        tmfclose(fp);
        return;
    }
7603 7604
    memset(cmd, 0, MAX_SQL_SIZE);
    cmd_len = 0;
H
hzcheng 已提交
7605 7606
  }

7607
  t = taosGetTimestampMs() - t;
7608
  printf("run %s took %.6f second(s)\n\n", sqlFile, t);
7609

7610 7611 7612 7613
  tmfree(cmd);
  tmfree(line);
  tmfclose(fp);
  return;
H
hzcheng 已提交
7614 7615
}

7616
static void testMetaFile() {
7617
    if (INSERT_TEST == g_args.test_mode) {
7618 7619
      if (g_Dbs.cfgDir[0])
          taos_options(TSDB_OPTION_CONFIGDIR, g_Dbs.cfgDir);
7620

7621
      insertTestProcess();
7622

7623
    } else if (QUERY_TEST == g_args.test_mode) {
7624 7625
      if (g_queryInfo.cfgDir[0])
          taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir);
7626

7627
      queryTestProcess();
7628

7629
    } else if (SUBSCRIBE_TEST == g_args.test_mode) {
7630 7631
      if (g_queryInfo.cfgDir[0])
          taos_options(TSDB_OPTION_CONFIGDIR, g_queryInfo.cfgDir);
7632

7633
      subscribeTestProcess();
7634

7635 7636 7637
    }  else {
      ;
    }
7638
}
7639

7640
static void queryResult() {
7641
  // query data
7642

7643
  pthread_t read_id;
7644 7645 7646 7647
  threadInfo *pThreadInfo = malloc(sizeof(threadInfo));
  assert(pThreadInfo);
  pThreadInfo->start_time = 1500000000000;  // 2017-07-14 10:40:00.000
  pThreadInfo->start_table_from = 0;
7648

7649
  //pThreadInfo->do_aggreFunc = g_Dbs.do_aggreFunc;
7650
  if (g_args.use_metric) {
7651 7652 7653 7654
    pThreadInfo->ntables = g_Dbs.db[0].superTbls[0].childTblCount;
    pThreadInfo->end_table_to = g_Dbs.db[0].superTbls[0].childTblCount - 1;
    pThreadInfo->superTblInfo = &g_Dbs.db[0].superTbls[0];
    tstrncpy(pThreadInfo->tb_prefix,
7655 7656
          g_Dbs.db[0].superTbls[0].childTblPrefix, MAX_TB_NAME_SIZE);
  } else {
7657 7658 7659
    pThreadInfo->ntables = g_args.num_of_tables;
    pThreadInfo->end_table_to = g_args.num_of_tables -1;
    tstrncpy(pThreadInfo->tb_prefix, g_args.tb_prefix, MAX_TB_NAME_SIZE);
7660 7661
  }

7662
  pThreadInfo->taos = taos_connect(
7663 7664 7665 7666 7667
          g_Dbs.host,
          g_Dbs.user,
          g_Dbs.password,
          g_Dbs.db[0].dbName,
          g_Dbs.port);
7668
  if (pThreadInfo->taos == NULL) {
7669 7670
    errorPrint( "Failed to connect to TDengine, reason:%s\n",
            taos_errstr(NULL));
7671
    free(pThreadInfo);
7672 7673 7674
    exit(-1);
  }

7675
  tstrncpy(pThreadInfo->filePath, g_Dbs.resultFile, MAX_FILE_NAME_LEN);
7676 7677

  if (!g_Dbs.use_metric) {
7678
    pthread_create(&read_id, NULL, readTable, pThreadInfo);
7679
  } else {
7680
    pthread_create(&read_id, NULL, readMetric, pThreadInfo);
7681 7682
  }
  pthread_join(read_id, NULL);
7683 7684
  taos_close(pThreadInfo->taos);
  free(pThreadInfo);
7685 7686
}

7687 7688
static void testCmdLine() {

7689 7690 7691 7692 7693 7694 7695 7696 7697 7698
  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);
  }

7699 7700
  g_args.test_mode = INSERT_TEST;
  insertTestProcess();
7701

7702
  if (false == g_Dbs.insert_only)
7703
    queryResult();
7704 7705
}

7706 7707 7708
int main(int argc, char *argv[]) {
  parse_args(argc, argv, &g_args);

7709
  debugPrint("meta file: %s\n", g_args.metaFile);
7710 7711 7712

  if (g_args.metaFile) {
    initOfInsertMeta();
7713
    initOfQueryMeta();
7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726

    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(
7727 7728 7729 7730
          g_Dbs.host,
          g_Dbs.user,
          g_Dbs.password,
          g_Dbs.db[0].dbName,
7731
          g_Dbs.port);
7732
      querySqlFile(qtaos, g_args.sqlFile);
7733 7734 7735 7736 7737
      taos_close(qtaos);

    } else {
      testCmdLine();
    }
7738 7739 7740

    if (g_dupstr)
        free(g_dupstr);
H
hzcheng 已提交
7741
  }
7742 7743

  return 0;
H
hzcheng 已提交
7744
}
7745