indexComm.c 13.8 KB
Newer Older
dengyihao's avatar
add UT  
dengyihao 已提交
1 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
#include "indexComm.h"
dengyihao's avatar
add UT  
dengyihao 已提交
17 18
#include "index.h"
#include "indexInt.h"
dengyihao's avatar
dengyihao 已提交
19
#include "tcoding.h"
20
#include "tcompare.h"
dengyihao's avatar
dengyihao 已提交
21
#include "tdataformat.h"
22
#include "ttypes.h"
23
#include "tvariant.h"
dengyihao's avatar
add UT  
dengyihao 已提交
24

dengyihao's avatar
dengyihao 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#define INDEX_DATA_BOOL_NULL      0x02
#define INDEX_DATA_TINYINT_NULL   0x80
#define INDEX_DATA_SMALLINT_NULL  0x8000
#define INDEX_DATA_INT_NULL       0x80000000L
#define INDEX_DATA_BIGINT_NULL    0x8000000000000000L
#define INDEX_DATA_TIMESTAMP_NULL TSDB_DATA_BIGINT_NULL

#define INDEX_DATA_FLOAT_NULL    0x7FF00000           // it is an NAN
#define INDEX_DATA_DOUBLE_NULL   0x7FFFFF0000000000L  // an NAN
#define INDEX_DATA_NCHAR_NULL    0xFFFFFFFF
#define INDEX_DATA_BINARY_NULL   0xFF
#define INDEX_DATA_JSON_NULL     0xFFFFFFFF
#define INDEX_DATA_JSON_null     0xFFFFFFFE
#define INDEX_DATA_JSON_NOT_NULL 0x01

#define INDEX_DATA_UTINYINT_NULL  0xFF
#define INDEX_DATA_USMALLINT_NULL 0xFFFF
#define INDEX_DATA_UINT_NULL      0xFFFFFFFF
#define INDEX_DATA_UBIGINT_NULL   0xFFFFFFFFFFFFFFFFL

#define INDEX_DATA_NULL_STR   "NULL"
#define INDEX_DATA_NULL_STR_L "null"

dengyihao's avatar
add UT  
dengyihao 已提交
48 49 50
char JSON_COLUMN[] = "JSON";
char JSON_VALUE_DELIM = '&';

51
char* indexInt2str(int64_t val, char* dst, int radix) {
52
  char     buffer[65] = {0};
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
  char*    p;
  int64_t  new_val;
  uint64_t uval = (uint64_t)val;

  if (radix < 0) {
    if (val < 0) {
      *dst++ = '-';
      uval = (uint64_t)0 - uval; /* Avoid integer overflow in (-val) for LLONG_MIN (BUG#31799). */
    }
  }
  p = &buffer[sizeof(buffer) - 1];
  *p = '\0';
  new_val = (int64_t)(uval / 10);
  *--p = '0' + (char)(uval - (uint64_t)new_val * 10);
  val = new_val;

  while (val != 0) {
    new_val = val / 10;
    *--p = '0' + (char)(val - new_val * 10);
    val = new_val;
  }
  while ((*dst++ = *p++) != 0)
    ;
  return dst - 1;
}
dengyihao's avatar
dengyihao 已提交
78
__compar_fn_t indexGetCompar(int8_t type) {
dengyihao's avatar
dengyihao 已提交
79 80 81 82 83
  if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
    return (__compar_fn_t)strcmp;
  }
  return getComparFunc(type, 0);
}
84
static TExeCond tCompareLessThan(void* a, void* b, int8_t type) {
dengyihao's avatar
dengyihao 已提交
85
  __compar_fn_t func = indexGetCompar(type);
86
  return tCompare(func, QUERY_LESS_THAN, a, b, type);
87 88
}
static TExeCond tCompareLessEqual(void* a, void* b, int8_t type) {
dengyihao's avatar
dengyihao 已提交
89
  __compar_fn_t func = indexGetCompar(type);
90
  return tCompare(func, QUERY_LESS_EQUAL, a, b, type);
91 92
}
static TExeCond tCompareGreaterThan(void* a, void* b, int8_t type) {
dengyihao's avatar
dengyihao 已提交
93
  __compar_fn_t func = indexGetCompar(type);
94
  return tCompare(func, QUERY_GREATER_THAN, a, b, type);
95 96
}
static TExeCond tCompareGreaterEqual(void* a, void* b, int8_t type) {
dengyihao's avatar
dengyihao 已提交
97
  __compar_fn_t func = indexGetCompar(type);
98
  return tCompare(func, QUERY_GREATER_EQUAL, a, b, type);
99
}
100
TExeCond tCompare(__compar_fn_t func, int8_t cmptype, void* a, void* b, int8_t dtype) {
101
  if (dtype == TSDB_DATA_TYPE_BINARY || dtype == TSDB_DATA_TYPE_NCHAR || dtype == TSDB_DATA_TYPE_VARBINARY) {
102 103 104
    return tDoCompare(func, cmptype, a, b);
  }
#if 1
105 106 107 108 109 110 111 112 113
  if (dtype == TSDB_DATA_TYPE_TIMESTAMP) {
    int64_t va = taosStr2int64(a);
    int64_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
  } else if (dtype == TSDB_DATA_TYPE_BOOL || dtype == TSDB_DATA_TYPE_UTINYINT) {
    uint8_t va = taosStr2int64(a);
    uint8_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
  } else if (dtype == TSDB_DATA_TYPE_TINYINT) {
114 115 116
    int8_t va = taosStr2int64(a);
    int8_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
117
  } else if (dtype == TSDB_DATA_TYPE_SMALLINT) {
118 119 120
    int16_t va = taosStr2int64(a);
    int16_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
121 122 123 124 125
  } else if (dtype == TSDB_DATA_TYPE_USMALLINT) {
    uint16_t va = taosStr2int64(a);
    uint16_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
  } else if (dtype == TSDB_DATA_TYPE_INT) {
126 127 128
    int32_t va = taosStr2int64(a);
    int32_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
129 130 131 132 133
  } else if (dtype == TSDB_DATA_TYPE_UINT) {
    uint32_t va = taosStr2int64(a);
    uint32_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
  } else if (dtype == TSDB_DATA_TYPE_BIGINT) {
134 135 136
    int64_t va = taosStr2int64(a);
    int64_t vb = taosStr2int64(b);
    return tDoCompare(func, cmptype, &va, &vb);
137 138 139 140 141 142 143
  } else if (dtype == TSDB_DATA_TYPE_UBIGINT) {
    uint64_t va, vb;
    if (0 != toUInteger(a, strlen(a), 10, &va) || 0 != toUInteger(b, strlen(b), 10, &vb)) {
      return CONTINUE;
    }
    return tDoCompare(func, cmptype, &va, &vb);
  } else if (dtype == TSDB_DATA_TYPE_FLOAT) {
wafwerar's avatar
wafwerar 已提交
144
    float va = taosStr2Float(a, NULL);
145 146 147
    if (errno == ERANGE && va == -1) {
      return CONTINUE;
    }
wafwerar's avatar
wafwerar 已提交
148
    float vb = taosStr2Float(b, NULL);
149 150 151 152 153
    if (errno == ERANGE && va == -1) {
      return CONTINUE;
    }
    return tDoCompare(func, cmptype, &va, &vb);
  } else if (dtype == TSDB_DATA_TYPE_DOUBLE) {
wafwerar's avatar
wafwerar 已提交
154
    double va = taosStr2Double(a, NULL);
155 156 157
    if (errno == ERANGE && va == -1) {
      return CONTINUE;
    }
wafwerar's avatar
wafwerar 已提交
158
    double vb = taosStr2Double(b, NULL);
159 160 161 162
    if (errno == ERANGE && va == -1) {
      return CONTINUE;
    }
    return tDoCompare(func, cmptype, &va, &vb);
163
  }
164
  assert(0);
165 166 167
#endif
}
TExeCond tDoCompare(__compar_fn_t func, int8_t comparType, void* a, void* b) {
168 169
  // optime later
  int32_t ret = func(a, b);
170
  switch (comparType) {
171 172 173 174 175 176 177 178 179 180 181 182 183 184
    case QUERY_LESS_THAN: {
      if (ret < 0) return MATCH;
    } break;
    case QUERY_LESS_EQUAL: {
      if (ret <= 0) return MATCH;
      break;
    }
    case QUERY_GREATER_THAN: {
      if (ret > 0) return MATCH;
      break;
    }
    case QUERY_GREATER_EQUAL: {
      if (ret >= 0) return MATCH;
    }
dengyihao's avatar
dengyihao 已提交
185 186 187
    case QUERY_TERM: {
      if (ret == 0) return MATCH;
    }
188 189 190 191 192 193 194 195 196
  }
  return CONTINUE;
}

static TExeCond (*rangeCompare[])(void* a, void* b, int8_t type) = {tCompareLessThan, tCompareLessEqual,
                                                                    tCompareGreaterThan, tCompareGreaterEqual};

_cache_range_compare indexGetCompare(RangeType ty) { return rangeCompare[ty]; }

dengyihao's avatar
add UT  
dengyihao 已提交
197 198 199 200 201 202 203 204
char* indexPackJsonData(SIndexTerm* itm) {
  /*
   * |<-----colname---->|<-----dataType---->|<--------colVal---------->|
   * |<-----string----->|<-----uint8_t----->|<----depend on dataType-->|
   */
  uint8_t ty = INDEX_TYPE_GET_TYPE(itm->colType);

  int32_t sz = itm->nColName + itm->nColVal + sizeof(uint8_t) + sizeof(JSON_VALUE_DELIM) * 2 + 1;
wafwerar's avatar
wafwerar 已提交
205
  char*   buf = (char*)taosMemoryCalloc(1, sz);
dengyihao's avatar
add UT  
dengyihao 已提交
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
  char*   p = buf;

  memcpy(p, itm->colName, itm->nColName);
  p += itm->nColName;

  memcpy(p, &JSON_VALUE_DELIM, sizeof(JSON_VALUE_DELIM));
  p += sizeof(JSON_VALUE_DELIM);

  memcpy(p, &ty, sizeof(ty));
  p += sizeof(ty);

  memcpy(p, &JSON_VALUE_DELIM, sizeof(JSON_VALUE_DELIM));
  p += sizeof(JSON_VALUE_DELIM);

  memcpy(p, itm->colVal, itm->nColVal);

  return buf;
}
224

dengyihao's avatar
dengyihao 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
char* indexPackJsonDataPrefix(SIndexTerm* itm, int32_t* skip) {
  /*
   * |<-----colname---->|<-----dataType---->|<--------colVal---------->|
   * |<-----string----->|<-----uint8_t----->|<----depend on dataType-->|
   */
  uint8_t ty = INDEX_TYPE_GET_TYPE(itm->colType);

  int32_t sz = itm->nColName + itm->nColVal + sizeof(uint8_t) + sizeof(JSON_VALUE_DELIM) * 2 + 1;
  char*   buf = (char*)taosMemoryCalloc(1, sz);
  char*   p = buf;

  memcpy(p, itm->colName, itm->nColName);
  p += itm->nColName;

  memcpy(p, &JSON_VALUE_DELIM, sizeof(JSON_VALUE_DELIM));
  p += sizeof(JSON_VALUE_DELIM);

  memcpy(p, &ty, sizeof(ty));
  p += sizeof(ty);

  memcpy(p, &JSON_VALUE_DELIM, sizeof(JSON_VALUE_DELIM));
  p += sizeof(JSON_VALUE_DELIM);

  *skip = p - buf;

  return buf;
}
dengyihao's avatar
dengyihao 已提交
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297

int32_t indexConvertData(void* src, int8_t type, void** dst) {
  int tlen = -1;
  switch (type) {
    case TSDB_DATA_TYPE_TIMESTAMP:
      tlen = taosEncodeFixedI64(NULL, *(int64_t*)src);
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeFixedI64(dst, *(int64_t*)src);
      break;
    case TSDB_DATA_TYPE_BOOL:
    case TSDB_DATA_TYPE_UTINYINT:
      tlen = taosEncodeFixedU8(NULL, *(uint8_t*)src);
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeFixedU8(dst, *(uint8_t*)src);
      break;
    case TSDB_DATA_TYPE_TINYINT:
      tlen = taosEncodeFixedI8(NULL, *(uint8_t*)src);
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeFixedI8(dst, *(uint8_t*)src);
      break;
    case TSDB_DATA_TYPE_SMALLINT:
      tlen = taosEncodeFixedI16(NULL, *(int16_t*)src);
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeFixedI16(dst, *(int16_t*)src);
      break;
    case TSDB_DATA_TYPE_USMALLINT:
      tlen = taosEncodeFixedU16(NULL, *(uint16_t*)src);
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeFixedU16(dst, *(uint16_t*)src);
      break;
    case TSDB_DATA_TYPE_INT:
      tlen = taosEncodeFixedI32(NULL, *(int32_t*)src);
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeFixedI32(dst, *(int32_t*)src);
      break;
    case TSDB_DATA_TYPE_FLOAT:
      tlen = taosEncodeBinary(NULL, src, sizeof(float));
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeBinary(dst, src, sizeof(float));
      break;
    case TSDB_DATA_TYPE_UINT:
      tlen = taosEncodeFixedU32(NULL, *(uint32_t*)src);
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeFixedU32(dst, *(uint32_t*)src);
      break;
    case TSDB_DATA_TYPE_BIGINT:
dengyihao's avatar
dengyihao 已提交
298
      tlen = taosEncodeFixedI64(NULL, *(int64_t*)src);
dengyihao's avatar
dengyihao 已提交
299
      *dst = taosMemoryCalloc(1, tlen + 1);
dengyihao's avatar
dengyihao 已提交
300
      tlen = taosEncodeFixedI64(dst, *(int64_t*)src);
dengyihao's avatar
dengyihao 已提交
301 302 303 304 305 306 307
      break;
    case TSDB_DATA_TYPE_DOUBLE:
      tlen = taosEncodeBinary(NULL, src, sizeof(double));
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeBinary(dst, src, sizeof(double));
      break;
    case TSDB_DATA_TYPE_UBIGINT:
dengyihao's avatar
dengyihao 已提交
308
      tlen = taosEncodeFixedU64(NULL, *(uint64_t*)src);
dengyihao's avatar
dengyihao 已提交
309
      *dst = taosMemoryCalloc(1, tlen + 1);
dengyihao's avatar
dengyihao 已提交
310
      tlen = taosEncodeFixedU64(dst, *(uint64_t*)src);
dengyihao's avatar
dengyihao 已提交
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
      break;
    case TSDB_DATA_TYPE_NCHAR: {
      tlen = taosEncodeBinary(NULL, varDataVal(src), varDataLen(src));
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeBinary(dst, varDataVal(src), varDataLen(src));

      break;
    }
    case TSDB_DATA_TYPE_VARCHAR: {  // TSDB_DATA_TYPE_BINARY
      tlen = taosEncodeBinary(NULL, src, strlen(src));
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeBinary(dst, src, strlen(src));
      break;
    }
    case TSDB_DATA_TYPE_VARBINARY:
      tlen = taosEncodeBinary(NULL, src, strlen(src));
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeBinary(dst, src, strlen(src));
      break;
    default:
      TASSERT(0);
      break;
  }
wafwerar's avatar
wafwerar 已提交
334
  *dst = (char*)*dst - tlen;
335
  // indexMayFillNumbericData(*dst, tlen);
dengyihao's avatar
dengyihao 已提交
336 337
  return tlen;
}
338
int32_t indexConvertDataToStr(void* src, int8_t type, void** dst) {
339 340
  int     tlen = tDataTypes[type].bytes;
  int32_t bufSize = 64;
dengyihao's avatar
dengyihao 已提交
341 342
  switch (type) {
    case TSDB_DATA_TYPE_TIMESTAMP:
343
      *dst = taosMemoryCalloc(1, bufSize + 1);
344
      indexInt2str(*(int64_t*)src, *dst, -1);
dengyihao's avatar
dengyihao 已提交
345
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
346 347 348
      break;
    case TSDB_DATA_TYPE_BOOL:
    case TSDB_DATA_TYPE_UTINYINT:
349
      *dst = taosMemoryCalloc(1, bufSize + 1);
350
      indexInt2str(*(uint8_t*)src, *dst, 1);
dengyihao's avatar
dengyihao 已提交
351
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
352 353
      break;
    case TSDB_DATA_TYPE_TINYINT:
354
      *dst = taosMemoryCalloc(1, bufSize + 1);
355
      indexInt2str(*(int8_t*)src, *dst, 1);
dengyihao's avatar
dengyihao 已提交
356
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
357 358
      break;
    case TSDB_DATA_TYPE_SMALLINT:
359
      *dst = taosMemoryCalloc(1, bufSize + 1);
360
      indexInt2str(*(int16_t*)src, *dst, -1);
dengyihao's avatar
dengyihao 已提交
361
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
362 363
      break;
    case TSDB_DATA_TYPE_USMALLINT:
364
      *dst = taosMemoryCalloc(1, bufSize + 1);
365
      indexInt2str(*(uint16_t*)src, *dst, -1);
dengyihao's avatar
dengyihao 已提交
366
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
367 368
      break;
    case TSDB_DATA_TYPE_INT:
369
      *dst = taosMemoryCalloc(1, bufSize + 1);
370
      indexInt2str(*(int32_t*)src, *dst, -1);
dengyihao's avatar
dengyihao 已提交
371
      tlen = strlen(*dst);
372
      break;
dengyihao's avatar
dengyihao 已提交
373
    case TSDB_DATA_TYPE_UINT:
374
      *dst = taosMemoryCalloc(1, bufSize + 1);
375
      indexInt2str(*(uint32_t*)src, *dst, 1);
dengyihao's avatar
dengyihao 已提交
376
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
377 378
      break;
    case TSDB_DATA_TYPE_BIGINT:
379 380
      *dst = taosMemoryCalloc(1, bufSize + 1);
      sprintf(*dst, "%" PRIu64, *(uint64_t*)src);
dengyihao's avatar
dengyihao 已提交
381
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
382 383
      break;
    case TSDB_DATA_TYPE_UBIGINT:
384
      *dst = taosMemoryCalloc(1, bufSize + 1);
385
      indexInt2str(*(uint64_t*)src, *dst, 1);
dengyihao's avatar
dengyihao 已提交
386
      tlen = strlen(*dst);
387 388 389
    case TSDB_DATA_TYPE_FLOAT:
      *dst = taosMemoryCalloc(1, bufSize + 1);
      sprintf(*dst, "%.9lf", *(float*)src);
dengyihao's avatar
dengyihao 已提交
390
      tlen = strlen(*dst);
391 392 393 394
      break;
    case TSDB_DATA_TYPE_DOUBLE:
      *dst = taosMemoryCalloc(1, bufSize + 1);
      sprintf(*dst, "%.9lf", *(double*)src);
dengyihao's avatar
dengyihao 已提交
395
      tlen = strlen(*dst);
dengyihao's avatar
dengyihao 已提交
396
      break;
397 398 399 400
    case TSDB_DATA_TYPE_NCHAR: {
      tlen = taosEncodeBinary(NULL, varDataVal(src), varDataLen(src));
      *dst = taosMemoryCalloc(1, tlen + 1);
      tlen = taosEncodeBinary(dst, varDataVal(src), varDataLen(src));
dengyihao's avatar
dengyihao 已提交
401
      *dst = (char*)*dst - tlen;
dengyihao's avatar
dengyihao 已提交
402
      break;
403 404
    }
    case TSDB_DATA_TYPE_VARCHAR: {  // TSDB_DATA_TYPE_BINARY
dengyihao's avatar
dengyihao 已提交
405
      tlen = taosEncodeBinary(NULL, varDataVal(src), varDataLen(src));
406
      *dst = taosMemoryCalloc(1, tlen + 1);
dengyihao's avatar
dengyihao 已提交
407
      tlen = taosEncodeBinary(dst, varDataVal(src), varDataLen(src));
dengyihao's avatar
dengyihao 已提交
408
      *dst = (char*)*dst - tlen;
dengyihao's avatar
dengyihao 已提交
409
      break;
410 411
    }
    case TSDB_DATA_TYPE_VARBINARY:
dengyihao's avatar
dengyihao 已提交
412
      tlen = taosEncodeBinary(NULL, varDataVal(src), varDataLen(src));
413
      *dst = taosMemoryCalloc(1, tlen + 1);
dengyihao's avatar
dengyihao 已提交
414
      tlen = taosEncodeBinary(dst, varDataVal(src), varDataLen(src));
dengyihao's avatar
dengyihao 已提交
415
      *dst = (char*)*dst - tlen;
416
      break;
dengyihao's avatar
dengyihao 已提交
417
    default:
418
      TASSERT(0);
dengyihao's avatar
dengyihao 已提交
419
      break;
dengyihao's avatar
dengyihao 已提交
420 421 422
  }
  return tlen;
}