PostgreSQL Source Code  git master
equalfuncs.c File Reference
#include "postgres.h"
#include "miscadmin.h"
#include "utils/datum.h"
#include "equalfuncs.funcs.c"
#include "equalfuncs.switch.c"
Include dependency graph for equalfuncs.c:

Go to the source code of this file.

Macros

#define COMPARE_SCALAR_FIELD(fldname)
 
#define COMPARE_NODE_FIELD(fldname)
 
#define COMPARE_BITMAPSET_FIELD(fldname)
 
#define COMPARE_STRING_FIELD(fldname)
 
#define equalstr(a, b)    (((a) != NULL && (b) != NULL) ? (strcmp(a, b) == 0) : (a) == (b))
 
#define COMPARE_ARRAY_FIELD(fldname)
 
#define COMPARE_POINTER_FIELD(fldname, sz)
 
#define COMPARE_LOCATION_FIELD(fldname)    ((void) 0)
 
#define COMPARE_COERCIONFORM_FIELD(fldname)    ((void) 0)
 

Functions

static bool _equalConst (const Const *a, const Const *b)
 
static bool _equalExtensibleNode (const ExtensibleNode *a, const ExtensibleNode *b)
 
static bool _equalA_Const (const A_Const *a, const A_Const *b)
 
static bool _equalBitmapset (const Bitmapset *a, const Bitmapset *b)
 
static bool _equalList (const List *a, const List *b)
 
bool equal (const void *a, const void *b)
 

Macro Definition Documentation

◆ COMPARE_ARRAY_FIELD

#define COMPARE_ARRAY_FIELD (   fldname)
Value:
do { \
if (memcmp(a->fldname, b->fldname, sizeof(a->fldname)) != 0) \
return false; \
} while (0)
int b
Definition: isn.c:70
int a
Definition: isn.c:69

Definition at line 66 of file equalfuncs.c.

◆ COMPARE_BITMAPSET_FIELD

#define COMPARE_BITMAPSET_FIELD (   fldname)
Value:
do { \
if (!bms_equal(a->fldname, b->fldname)) \
return false; \
} while (0)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:142

Definition at line 48 of file equalfuncs.c.

◆ COMPARE_COERCIONFORM_FIELD

#define COMPARE_COERCIONFORM_FIELD (   fldname)     ((void) 0)

Definition at line 84 of file equalfuncs.c.

◆ COMPARE_LOCATION_FIELD

#define COMPARE_LOCATION_FIELD (   fldname)     ((void) 0)

Definition at line 80 of file equalfuncs.c.

◆ COMPARE_NODE_FIELD

#define COMPARE_NODE_FIELD (   fldname)
Value:
do { \
if (!equal(a->fldname, b->fldname)) \
return false; \
} while (0)
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223

Definition at line 41 of file equalfuncs.c.

◆ COMPARE_POINTER_FIELD

#define COMPARE_POINTER_FIELD (   fldname,
  sz 
)
Value:
do { \
if (memcmp(a->fldname, b->fldname, (sz)) != 0) \
return false; \
} while (0)

Definition at line 73 of file equalfuncs.c.

◆ COMPARE_SCALAR_FIELD

#define COMPARE_SCALAR_FIELD (   fldname)
Value:
do { \
if (a->fldname != b->fldname) \
return false; \
} while (0)

Definition at line 34 of file equalfuncs.c.

◆ COMPARE_STRING_FIELD

#define COMPARE_STRING_FIELD (   fldname)
Value:
do { \
if (!equalstr(a->fldname, b->fldname)) \
return false; \
} while (0)
#define equalstr(a, b)
Definition: equalfuncs.c:62

Definition at line 55 of file equalfuncs.c.

◆ equalstr

#define equalstr (   a,
  b 
)     (((a) != NULL && (b) != NULL) ? (strcmp(a, b) == 0) : (a) == (b))

Definition at line 62 of file equalfuncs.c.

Function Documentation

◆ _equalA_Const()

static bool _equalA_Const ( const A_Const a,
const A_Const b 
)
static

Definition at line 134 of file equalfuncs.c.

135 {
136  COMPARE_SCALAR_FIELD(isnull);
137  /* Hack for in-line val field. Also val is not valid if isnull is true */
138  if (!a->isnull &&
139  !equal(&a->val, &b->val))
140  return false;
141  COMPARE_LOCATION_FIELD(location);
142 
143  return true;
144 }
#define COMPARE_LOCATION_FIELD(fldname)
Definition: equalfuncs.c:80
#define COMPARE_SCALAR_FIELD(fldname)
Definition: equalfuncs.c:34

References a, b, COMPARE_LOCATION_FIELD, COMPARE_SCALAR_FIELD, and equal().

◆ _equalBitmapset()

static bool _equalBitmapset ( const Bitmapset a,
const Bitmapset b 
)
static

Definition at line 147 of file equalfuncs.c.

148 {
149  return bms_equal(a, b);
150 }

References a, b, and bms_equal().

◆ _equalConst()

static bool _equalConst ( const Const a,
const Const b 
)
static

Definition at line 96 of file equalfuncs.c.

97 {
98  COMPARE_SCALAR_FIELD(consttype);
99  COMPARE_SCALAR_FIELD(consttypmod);
100  COMPARE_SCALAR_FIELD(constcollid);
101  COMPARE_SCALAR_FIELD(constlen);
102  COMPARE_SCALAR_FIELD(constisnull);
103  COMPARE_SCALAR_FIELD(constbyval);
104  COMPARE_LOCATION_FIELD(location);
105 
106  /*
107  * We treat all NULL constants of the same type as equal. Someday this
108  * might need to change? But datumIsEqual doesn't work on nulls, so...
109  */
110  if (a->constisnull)
111  return true;
112  return datumIsEqual(a->constvalue, b->constvalue,
113  a->constbyval, a->constlen);
114 }
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition: datum.c:223

References a, b, COMPARE_LOCATION_FIELD, COMPARE_SCALAR_FIELD, and datumIsEqual().

◆ _equalExtensibleNode()

static bool _equalExtensibleNode ( const ExtensibleNode a,
const ExtensibleNode b 
)
static

Definition at line 117 of file equalfuncs.c.

118 {
119  const ExtensibleNodeMethods *methods;
120 
121  COMPARE_STRING_FIELD(extnodename);
122 
123  /* At this point, we know extnodename is the same for both nodes. */
124  methods = GetExtensibleNodeMethods(a->extnodename, false);
125 
126  /* compare the private fields */
127  if (!methods->nodeEqual(a, b))
128  return false;
129 
130  return true;
131 }
#define COMPARE_STRING_FIELD(fldname)
Definition: equalfuncs.c:55
const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
Definition: extensible.c:125
bool(* nodeEqual)(const struct ExtensibleNode *a, const struct ExtensibleNode *b)
Definition: extensible.h:68

References a, b, COMPARE_STRING_FIELD, GetExtensibleNodeMethods(), and ExtensibleNodeMethods::nodeEqual.

◆ _equalList()

static bool _equalList ( const List a,
const List b 
)
static

Definition at line 156 of file equalfuncs.c.

157 {
158  const ListCell *item_a;
159  const ListCell *item_b;
160 
161  /*
162  * Try to reject by simple scalar checks before grovelling through all the
163  * list elements...
164  */
166  COMPARE_SCALAR_FIELD(length);
167 
168  /*
169  * We place the switch outside the loop for the sake of efficiency; this
170  * may not be worth doing...
171  */
172  switch (a->type)
173  {
174  case T_List:
175  forboth(item_a, a, item_b, b)
176  {
177  if (!equal(lfirst(item_a), lfirst(item_b)))
178  return false;
179  }
180  break;
181  case T_IntList:
182  forboth(item_a, a, item_b, b)
183  {
184  if (lfirst_int(item_a) != lfirst_int(item_b))
185  return false;
186  }
187  break;
188  case T_OidList:
189  forboth(item_a, a, item_b, b)
190  {
191  if (lfirst_oid(item_a) != lfirst_oid(item_b))
192  return false;
193  }
194  break;
195  case T_XidList:
196  forboth(item_a, a, item_b, b)
197  {
198  if (lfirst_xid(item_a) != lfirst_xid(item_b))
199  return false;
200  }
201  break;
202  default:
203  elog(ERROR, "unrecognized list node type: %d",
204  (int) a->type);
205  return false; /* keep compiler quiet */
206  }
207 
208  /*
209  * If we got here, we should have run out of elements of both lists
210  */
211  Assert(item_a == NULL);
212  Assert(item_b == NULL);
213 
214  return true;
215 }
#define Assert(condition)
Definition: c.h:858
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define lfirst(lc)
Definition: pg_list.h:172
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
#define lfirst_int(lc)
Definition: pg_list.h:173
#define lfirst_oid(lc)
Definition: pg_list.h:174
#define lfirst_xid(lc)
Definition: pg_list.h:175
const char * type

References a, Assert, b, COMPARE_SCALAR_FIELD, elog, equal(), ERROR, forboth, lfirst, lfirst_int, lfirst_oid, lfirst_xid, and type.

Referenced by equal().

◆ equal()

bool equal ( const void *  a,
const void *  b 
)

Definition at line 223 of file equalfuncs.c.

224 {
225  bool retval;
226 
227  if (a == b)
228  return true;
229 
230  /*
231  * note that a!=b, so only one of them can be NULL
232  */
233  if (a == NULL || b == NULL)
234  return false;
235 
236  /*
237  * are they the same type of nodes?
238  */
239  if (nodeTag(a) != nodeTag(b))
240  return false;
241 
242  /* Guard against stack overflow due to overly complex expressions */
244 
245  switch (nodeTag(a))
246  {
247 #include "equalfuncs.switch.c"
248 
249  case T_List:
250  case T_IntList:
251  case T_OidList:
252  case T_XidList:
253  retval = _equalList(a, b);
254  break;
255 
256  default:
257  elog(ERROR, "unrecognized node type: %d",
258  (int) nodeTag(a));
259  retval = false; /* keep compiler quiet */
260  break;
261  }
262 
263  return retval;
264 }
static bool _equalList(const List *a, const List *b)
Definition: equalfuncs.c:156
#define nodeTag(nodeptr)
Definition: nodes.h:133
void check_stack_depth(void)
Definition: postgres.c:3531

References _equalList(), a, b, check_stack_depth(), elog, ERROR, and nodeTag.

Referenced by _equalA_Const(), _equalList(), add_row_identity_var(), add_sp_item_to_pathtarget(), add_unique_group_var(), addRangeClause(), AlterPublicationTables(), ATExecMergePartitions(), calc_hist_selectivity_scalar(), calc_length_hist_frac(), check_new_partition_bound(), check_partition_bounds_for_split_list(), check_partitions_for_split(), check_ungrouped_columns_walker(), clause_is_strict_for(), CompareIndexInfo(), convert_subquery_pathkeys(), create_projection_path(), CreateStatistics(), deparseParam(), deparseVar(), dependencies_clauselist_selectivity(), dependency_is_compatible_expression(), ec_member_matches_foreign(), equalPolicy(), equalRuleLocks(), estimate_multivariate_ndistinct(), examine_variable(), ExecInitWindowAgg(), expand_grouping_sets(), exprs_known_equal(), finalize_grouping_exprs_walker(), find_compatible_agg(), find_ec_member_matching_expr(), find_em_for_rel_target(), find_list_position(), find_minmax_agg_replacement_param(), findTargetlistEntrySQL92(), findTargetlistEntrySQL99(), fix_expr_common(), fix_indexqual_operand(), get_eclass_for_sort_expr(), get_partition_for_tuple(), grouping_planner(), infer_collation_opclass_match(), is_exprlist_member(), length_hist_bsearch(), list_delete(), list_member(), match_boolean_partition_clause(), match_clause_to_partition_key(), match_eclasses_to_foreign_key_col(), match_expr_to_partition_keys(), match_index_to_operand(), matches_boolean_partition_clause(), maybe_reread_subscription(), mcv_match_expression(), MergeAttributes(), MergeCheckConstraint(), MergeWithExistingConstraint(), operator_predicate_proof(), optimize_window_clauses(), pg_parse_query(), pg_plan_query(), pg_rewrite_query(), plan_union_children(), predicate_implied_by_simple_clause(), predicate_refuted_by_simple_clause(), process_duplicate_ors(), process_equivalence(), process_matched_tle(), process_subquery_nestloop_params(), rbound_bsearch(), recomputeNamespacePath(), reconsider_full_join_clause(), reconsider_outer_join_clause(), RelationGetIndexAttrBitmap(), replace_nestloop_param_placeholdervar(), replace_nestloop_param_var(), search_indexed_tlist_for_sortgroupref(), stat_find_expression(), tlist_member(), tlist_same_exprs(), transformIndexConstraints(), transformPartitionBound(), transformPartitionCmdForMerge(), transformWindowFuncCall(), and trivial_subqueryscan().