nodesEqualFuncs.c 6.1 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/>.
 */

16
#include "querynodes.h"
17

X
Xiaoyu Wang 已提交
18 19 20 21 22
#define COMPARE_SCALAR_FIELD(fldname)           \
  do {                                          \
    if (a->fldname != b->fldname) return false; \
  } while (0)

23 24 25 26 27 28
#define COMPARE_STRING(a, b) (((a) != NULL && (b) != NULL) ? (strcmp((a), (b)) == 0) : (a) == (b))

#define COMPARE_VARDATA(a, b)                                                                                   \
  (((a) != NULL && (b) != NULL)                                                                                 \
       ? (varDataLen((a)) == varDataLen((b)) && memcmp(varDataVal((a)), varDataVal((b)), varDataLen((a))) == 0) \
       : (a) == (b))
X
Xiaoyu Wang 已提交
29 30 31 32 33 34

#define COMPARE_STRING_FIELD(fldname)                          \
  do {                                                         \
    if (!COMPARE_STRING(a->fldname, b->fldname)) return false; \
  } while (0)

35 36 37 38 39 40 41 42 43 44
#define COMPARE_VARDATA_FIELD(fldname)                          \
  do {                                                          \
    if (!COMPARE_VARDATA(a->fldname, b->fldname)) return false; \
  } while (0)

#define COMPARE_OBJECT_FIELD(fldname, equalFunc)          \
  do {                                                    \
    if (!equalFunc(a->fldname, b->fldname)) return false; \
  } while (0)

X
Xiaoyu Wang 已提交
45 46 47 48 49 50 51 52 53
#define COMPARE_NODE_FIELD(fldname)                            \
  do {                                                         \
    if (!nodesEqualNode(a->fldname, b->fldname)) return false; \
  } while (0)

#define COMPARE_NODE_LIST_FIELD(fldname)                          \
  do {                                                            \
    if (!nodeNodeListEqual(a->fldname, b->fldname)) return false; \
  } while (0)
54

55
static bool nodeNodeListEqual(const SNodeList* a, const SNodeList* b) {
56 57 58 59 60 61 62 63
  if (a == b) {
    return true;
  }

  if (NULL == a || NULL == b) {
    return false;
  }

64
  if (LIST_LENGTH(a) != LIST_LENGTH(b)) {
65 66 67
    return false;
  }

X
Xiaoyu Wang 已提交
68
  SNode *na, *nb;
69 70
  FORBOTH(na, a, nb, b) {
    if (!nodesEqualNode(na, nb)) {
71 72 73 74 75 76
      return false;
    }
  }
  return true;
}

77 78 79 80
static bool dataTypeEqual(SDataType a, SDataType b) {
  return a.type == b.type && a.bytes == b.bytes && a.precision == b.precision && a.scale == b.scale;
}

81 82 83 84
static bool columnNodeEqual(const SColumnNode* a, const SColumnNode* b) {
  COMPARE_STRING_FIELD(dbName);
  COMPARE_STRING_FIELD(tableName);
  COMPARE_STRING_FIELD(colName);
D
dapan1121 已提交
85
  COMPARE_STRING_FIELD(tableAlias);
86 87 88 89
  return true;
}

static bool valueNodeEqual(const SValueNode* a, const SValueNode* b) {
90
  COMPARE_OBJECT_FIELD(node.resType, dataTypeEqual);
91
  COMPARE_STRING_FIELD(literal);
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
  switch (a->node.resType.type) {
    case TSDB_DATA_TYPE_BOOL:
    case TSDB_DATA_TYPE_TINYINT:
    case TSDB_DATA_TYPE_SMALLINT:
    case TSDB_DATA_TYPE_INT:
    case TSDB_DATA_TYPE_BIGINT:
    case TSDB_DATA_TYPE_UTINYINT:
    case TSDB_DATA_TYPE_USMALLINT:
    case TSDB_DATA_TYPE_UINT:
    case TSDB_DATA_TYPE_UBIGINT:
    case TSDB_DATA_TYPE_FLOAT:
    case TSDB_DATA_TYPE_DOUBLE:
    case TSDB_DATA_TYPE_TIMESTAMP:
      COMPARE_SCALAR_FIELD(typeData);
      break;
    case TSDB_DATA_TYPE_VARCHAR:
    case TSDB_DATA_TYPE_VARBINARY:
    case TSDB_DATA_TYPE_NCHAR:
D
Dingle Zhang 已提交
110
    case TSDB_DATA_TYPE_GEOMETRY:
111 112 113 114 115 116 117 118 119
      COMPARE_VARDATA_FIELD(datum.p);
      break;
    case TSDB_DATA_TYPE_JSON:
    case TSDB_DATA_TYPE_DECIMAL:
    case TSDB_DATA_TYPE_BLOB:
      return false;
    default:
      break;
  }
120 121 122 123 124 125 126 127 128 129 130 131
  return true;
}

static bool operatorNodeEqual(const SOperatorNode* a, const SOperatorNode* b) {
  COMPARE_SCALAR_FIELD(opType);
  COMPARE_NODE_FIELD(pLeft);
  COMPARE_NODE_FIELD(pRight);
  return true;
}

static bool logicConditionNodeEqual(const SLogicConditionNode* a, const SLogicConditionNode* b) {
  COMPARE_SCALAR_FIELD(condType);
132
  COMPARE_NODE_LIST_FIELD(pParameterList);
133 134 135 136 137
  return true;
}

static bool functionNodeEqual(const SFunctionNode* a, const SFunctionNode* b) {
  COMPARE_SCALAR_FIELD(funcId);
X
Xiaoyu Wang 已提交
138
  COMPARE_STRING_FIELD(functionName);
139
  COMPARE_NODE_LIST_FIELD(pParameterList);
140 141 142
  return true;
}

X
Xiaoyu Wang 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155
static bool whenThenNodeEqual(const SWhenThenNode* a, const SWhenThenNode* b) {
  COMPARE_NODE_FIELD(pWhen);
  COMPARE_NODE_FIELD(pThen);
  return true;
}

static bool caseWhenNodeEqual(const SCaseWhenNode* a, const SCaseWhenNode* b) {
  COMPARE_NODE_FIELD(pCase);
  COMPARE_NODE_FIELD(pElse);
  COMPARE_NODE_LIST_FIELD(pWhenThenList);
  return true;
}

156
bool nodesEqualNode(const SNode* a, const SNode* b) {
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
  if (a == b) {
    return true;
  }

  if (NULL == a || NULL == b) {
    return false;
  }

  if (nodeType(a) != nodeType(b)) {
    return false;
  }

  switch (nodeType(a)) {
    case QUERY_NODE_COLUMN:
      return columnNodeEqual((const SColumnNode*)a, (const SColumnNode*)b);
    case QUERY_NODE_VALUE:
      return valueNodeEqual((const SValueNode*)a, (const SValueNode*)b);
    case QUERY_NODE_OPERATOR:
      return operatorNodeEqual((const SOperatorNode*)a, (const SOperatorNode*)b);
    case QUERY_NODE_LOGIC_CONDITION:
      return logicConditionNodeEqual((const SLogicConditionNode*)a, (const SLogicConditionNode*)b);
    case QUERY_NODE_FUNCTION:
      return functionNodeEqual((const SFunctionNode*)a, (const SFunctionNode*)b);
X
Xiaoyu Wang 已提交
180 181 182 183
    case QUERY_NODE_WHEN_THEN:
      return whenThenNodeEqual((const SWhenThenNode*)a, (const SWhenThenNode*)b);
    case QUERY_NODE_CASE_WHEN:
      return caseWhenNodeEqual((const SCaseWhenNode*)a, (const SCaseWhenNode*)b);
184 185 186 187 188
    case QUERY_NODE_REAL_TABLE:
    case QUERY_NODE_TEMP_TABLE:
    case QUERY_NODE_JOIN_TABLE:
    case QUERY_NODE_GROUPING_SET:
    case QUERY_NODE_ORDER_BY_EXPR:
189
    case QUERY_NODE_LIMIT:
X
Xiaoyu Wang 已提交
190
      return false;
191 192 193 194 195 196
    default:
      break;
  }

  return false;
}