tvariant.c 7.5 KB
Newer Older
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/>.
 */

S
common  
Shengliang Guan 已提交
16 17
#define _DEFAULT_SOURCE
#include "tvariant.h"
18
#include "ttime.h"
19
#include "ttokendef.h"
20
#include "tvariant.h"
21

X
Xiaoyu Wang 已提交
22
int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value) {
23
  errno = 0;
X
Xiaoyu Wang 已提交
24
  char *endPtr = NULL;
25

wafwerar's avatar
wafwerar 已提交
26
  *value = taosStr2Int64(z, &endPtr, base);
X
Xiaoyu Wang 已提交
27
  if (errno == ERANGE || errno == EINVAL || endPtr - z != n) {
28 29 30 31 32 33 34
    errno = 0;
    return -1;
  }

  return 0;
}

X
Xiaoyu Wang 已提交
35 36 37
int32_t toUInteger(const char *z, int32_t n, int32_t base, uint64_t *value) {
  errno = 0;
  char *endPtr = NULL;
38

X
Xiaoyu Wang 已提交
39
  const char *p = z;
H
Haojun Liao 已提交
40 41
  while (*p == ' ') p++;
  if (*p == '-') {
X
Xiaoyu Wang 已提交
42 43
    return -1;
  }
X
Xiaoyu Wang 已提交
44

wafwerar's avatar
wafwerar 已提交
45
  *value = taosStr2UInt64(z, &endPtr, base);
X
Xiaoyu Wang 已提交
46 47 48
  if (errno == ERANGE || errno == EINVAL || endPtr - z != n) {
    errno = 0;
    return -1;
49
  }
X
Xiaoyu Wang 已提交
50

X
Xiaoyu Wang 已提交
51
  return 0;
52
}
H
Haojun Liao 已提交
53

54
/**
H
Haojun Liao 已提交
55
 * create SVariant from binary string, not ascii data
56 57 58 59 60
 * @param pVar
 * @param pz
 * @param len
 * @param type
 */
H
Haojun Liao 已提交
61
void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uint32_t type) {
62 63 64
  switch (type) {
    case TSDB_DATA_TYPE_BOOL:
    case TSDB_DATA_TYPE_TINYINT: {
65
      pVar->nLen = tDataTypes[type].bytes;
66
      pVar->i = GET_INT8_VAL(pz);
67 68 69
      break;
    }
    case TSDB_DATA_TYPE_UTINYINT: {
70
      pVar->nLen = tDataTypes[type].bytes;
71
      pVar->u = GET_UINT8_VAL(pz);
72 73 74
      break;
    }
    case TSDB_DATA_TYPE_SMALLINT: {
75
      pVar->nLen = tDataTypes[type].bytes;
76
      pVar->i = GET_INT16_VAL(pz);
77 78 79
      break;
    }
    case TSDB_DATA_TYPE_USMALLINT: {
80
      pVar->nLen = tDataTypes[type].bytes;
81
      pVar->u = GET_UINT16_VAL(pz);
82 83 84
      break;
    }
    case TSDB_DATA_TYPE_INT: {
85
      pVar->nLen = tDataTypes[type].bytes;
86
      pVar->i = GET_INT32_VAL(pz);
87 88 89
      break;
    }
    case TSDB_DATA_TYPE_UINT: {
90
      pVar->nLen = tDataTypes[type].bytes;
91
      pVar->u = GET_UINT32_VAL(pz);
92 93 94 95
      break;
    }
    case TSDB_DATA_TYPE_BIGINT:
    case TSDB_DATA_TYPE_TIMESTAMP: {
96
      pVar->nLen = tDataTypes[type].bytes;
97
      pVar->i = GET_INT64_VAL(pz);
98 99 100
      break;
    }
    case TSDB_DATA_TYPE_UBIGINT: {
101
      pVar->nLen = tDataTypes[type].bytes;
102
      pVar->u = GET_UINT64_VAL(pz);
103 104 105
      break;
    }
    case TSDB_DATA_TYPE_DOUBLE: {
106
      pVar->nLen = tDataTypes[type].bytes;
H
Haojun Liao 已提交
107
      pVar->d = GET_DOUBLE_VAL(pz);
108 109 110
      break;
    }
    case TSDB_DATA_TYPE_FLOAT: {
111
      pVar->nLen = tDataTypes[type].bytes;
112
      pVar->f = GET_FLOAT_VAL(pz);
113 114
      break;
    }
X
Xiaoyu Wang 已提交
115
    case TSDB_DATA_TYPE_NCHAR: {  // here we get the nchar length from raw binary bits length
116
      size_t lenInwchar = len / TSDB_NCHAR_SIZE;
117

wafwerar's avatar
wafwerar 已提交
118
      pVar->ucs4 = taosMemoryCalloc(1, (lenInwchar + 1) * TSDB_NCHAR_SIZE);
wafwerar's avatar
wafwerar 已提交
119
      memcpy(pVar->ucs4, pz, lenInwchar * TSDB_NCHAR_SIZE);
120
      pVar->nLen = (int32_t)len;
X
Xiaoyu Wang 已提交
121

122 123
      break;
    }
124
    case TSDB_DATA_TYPE_BINARY: {  // todo refactor, extract a method
wafwerar's avatar
wafwerar 已提交
125
      pVar->pz = taosMemoryCalloc(len + 1, sizeof(char));
126
      memcpy(pVar->pz, pz, len);
127
      pVar->nLen = (int32_t)len;
128 129
      break;
    }
X
Xiaoyu Wang 已提交
130

131
    default:
132
      pVar->i = GET_INT32_VAL(pz);
133
      pVar->nLen = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
134
  }
X
Xiaoyu Wang 已提交
135

136 137 138
  pVar->nType = type;
}

H
Haojun Liao 已提交
139
void taosVariantDestroy(SVariant *pVar) {
140
  if (pVar == NULL) return;
X
Xiaoyu Wang 已提交
141

X
Xiaoyu Wang 已提交
142 143
  if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR ||
      pVar->nType == TSDB_DATA_TYPE_JSON) {
wafwerar's avatar
wafwerar 已提交
144
    taosMemoryFreeClear(pVar->pz);
145 146
    pVar->nLen = 0;
  }
weixin_48148422's avatar
weixin_48148422 已提交
147 148

  // NOTE: this is only for string array
W
wpan 已提交
149
  if (pVar->nType == TSDB_DATA_TYPE_POINTER_ARRAY) {
weixin_48148422's avatar
weixin_48148422 已提交
150
    size_t num = taosArrayGetSize(pVar->arr);
X
Xiaoyu Wang 已提交
151 152
    for (size_t i = 0; i < num; i++) {
      void *p = taosArrayGetP(pVar->arr, i);
wafwerar's avatar
wafwerar 已提交
153
      taosMemoryFree(p);
weixin_48148422's avatar
weixin_48148422 已提交
154 155 156
    }
    taosArrayDestroy(pVar->arr);
    pVar->arr = NULL;
W
wpan 已提交
157 158 159
  } else if (pVar->nType == TSDB_DATA_TYPE_VALUE_ARRAY) {
    taosArrayDestroy(pVar->arr);
    pVar->arr = NULL;
weixin_48148422's avatar
weixin_48148422 已提交
160
  }
161 162
}

H
Haojun Liao 已提交
163
void taosVariantAssign(SVariant *pDst, const SVariant *pSrc) {
164
  if (pSrc == NULL || pDst == NULL) return;
X
Xiaoyu Wang 已提交
165

H
Haojun Liao 已提交
166
  pDst->nType = pSrc->nType;
X
Xiaoyu Wang 已提交
167 168
  if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR ||
      pSrc->nType == TSDB_DATA_TYPE_JSON) {
H
Haojun Liao 已提交
169
    int32_t len = pSrc->nLen + TSDB_NCHAR_SIZE;
wafwerar's avatar
wafwerar 已提交
170
    char   *p = taosMemoryRealloc(pDst->pz, len);
H
Haojun Liao 已提交
171 172
    assert(p);

H
Haojun Liao 已提交
173
    memset(p, 0, len);
H
Haojun Liao 已提交
174 175
    pDst->pz = p;

H
Haojun Liao 已提交
176 177
    memcpy(pDst->pz, pSrc->pz, pSrc->nLen);
    pDst->nLen = pSrc->nLen;
H
Haojun Liao 已提交
178 179 180
    return;
  }

181
  if (IS_NUMERIC_TYPE(pSrc->nType) || (pSrc->nType == TSDB_DATA_TYPE_BOOL)) {
182
    pDst->i = pSrc->i;
W
wpan 已提交
183
  } else if (pSrc->nType == TSDB_DATA_TYPE_POINTER_ARRAY) {  // this is only for string array
weixin_48148422's avatar
weixin_48148422 已提交
184
    size_t num = taosArrayGetSize(pSrc->arr);
X
Xiaoyu Wang 已提交
185 186 187 188
    pDst->arr = taosArrayInit(num, sizeof(char *));
    for (size_t i = 0; i < num; i++) {
      char *p = (char *)taosArrayGetP(pSrc->arr, i);
      char *n = strdup(p);
weixin_48148422's avatar
weixin_48148422 已提交
189 190
      taosArrayPush(pDst->arr, &n);
    }
W
wpan 已提交
191
  } else if (pSrc->nType == TSDB_DATA_TYPE_VALUE_ARRAY) {
X
Xiaoyu Wang 已提交
192 193 194 195 196 197 198 199
    size_t num = taosArrayGetSize(pSrc->arr);
    pDst->arr = taosArrayInit(num, sizeof(int64_t));
    pDst->nLen = pSrc->nLen;
    assert(pSrc->nLen == num);
    for (size_t i = 0; i < num; i++) {
      int64_t *p = taosArrayGet(pSrc->arr, i);
      taosArrayPush(pDst->arr, p);
    }
200
  }
H
Haojun Liao 已提交
201

W
wpan 已提交
202
  if (pDst->nType != TSDB_DATA_TYPE_POINTER_ARRAY && pDst->nType != TSDB_DATA_TYPE_VALUE_ARRAY) {
H
Haojun Liao 已提交
203
    pDst->nLen = tDataTypes[pDst->nType].bytes;
H
Haojun Liao 已提交
204
  }
205 206
}

X
Xiaoyu Wang 已提交
207
int32_t taosVariantCompare(const SVariant *p1, const SVariant *p2) {
H
Haojun Liao 已提交
208 209 210 211 212 213 214 215 216 217 218
  if (p1->nType == TSDB_DATA_TYPE_NULL && p2->nType == TSDB_DATA_TYPE_NULL) {
    return 0;
  }

  if (p1->nType == TSDB_DATA_TYPE_NULL) {
    return -1;
  }

  if (p2->nType == TSDB_DATA_TYPE_NULL) {
    return 1;
  }
219

220 221 222 223
  if (p1->nType == TSDB_DATA_TYPE_BINARY || p1->nType == TSDB_DATA_TYPE_NCHAR) {
    if (p1->nLen == p2->nLen) {
      return memcmp(p1->pz, p2->pz, p1->nLen);
    } else {
X
Xiaoyu Wang 已提交
224
      return p1->nLen > p2->nLen ? 1 : -1;
225
    }
226
  } else if (p1->nType == TSDB_DATA_TYPE_DOUBLE) {
H
Haojun Liao 已提交
227
    if (p1->d == p2->d) {
228 229
      return 0;
    } else {
X
Xiaoyu Wang 已提交
230
      return p1->d > p2->d ? 1 : -1;
231
    }
232 233 234 235 236 237
  } else if (p1->nType == TSDB_DATA_TYPE_FLOAT) {
    if (p1->f == p2->f) {
      return 0;
    } else {
      return p1->f > p2->f ? 1 : -1;
    }
238
  } else if (IS_UNSIGNED_NUMERIC_TYPE(p1->nType)) {
239
    if (p1->u == p2->u) {
240 241
      return 0;
    } else {
X
Xiaoyu Wang 已提交
242
      return p1->u > p2->u ? 1 : -1;
243 244
    }
  } else {
245
    if (p1->i == p2->i) {
246 247
      return 0;
    } else {
X
Xiaoyu Wang 已提交
248
      return p1->i > p2->i ? 1 : -1;
249
    }
250 251 252
  }
}

X
Xiaoyu Wang 已提交
253
char *taosVariantGet(SVariant *pVar, int32_t type) {
D
dapan1121 已提交
254
  switch (type) {
G
Ganlin Zhao 已提交
255
    case TSDB_DATA_TYPE_BOOL:
D
dapan1121 已提交
256 257
    case TSDB_DATA_TYPE_TINYINT:
    case TSDB_DATA_TYPE_SMALLINT:
G
Ganlin Zhao 已提交
258
    case TSDB_DATA_TYPE_INT:
D
dapan1121 已提交
259 260 261
    case TSDB_DATA_TYPE_BIGINT:
    case TSDB_DATA_TYPE_TIMESTAMP:
      return (char *)&pVar->i;
G
Ganlin Zhao 已提交
262 263 264 265 266
    case TSDB_DATA_TYPE_UTINYINT:
    case TSDB_DATA_TYPE_USMALLINT:
    case TSDB_DATA_TYPE_UINT:
    case TSDB_DATA_TYPE_UBIGINT:
      return (char *)&pVar->u;
D
dapan1121 已提交
267 268
    case TSDB_DATA_TYPE_DOUBLE:
      return (char *)&pVar->d;
269 270
    case TSDB_DATA_TYPE_FLOAT:
      return (char *)&pVar->f;
D
dapan1121 已提交
271
    case TSDB_DATA_TYPE_BINARY:
wmmhello's avatar
wmmhello 已提交
272
    case TSDB_DATA_TYPE_JSON:
D
dapan1121 已提交
273 274 275
      return (char *)pVar->pz;
    case TSDB_DATA_TYPE_NCHAR:
      return (char *)pVar->ucs4;
G
Ganlin Zhao 已提交
276
    default:
D
dapan1121 已提交
277 278 279 280 281
      return NULL;
  }

  return NULL;
}