CVS User Account cvsuser
Wed Oct 6 16:09:17 PDT 2004
Log Message:
-----------
Bugfix: The Slony1 log trigger assumed that if lookup_type_cache() 
returned an entry at all, that the eq_opr_finfo will be filled with
a valid operator call address. But this is not true for user defined
data types that do not have any equal operator at all. The log trigger
will now fall back to string comparision of the output format for
those data types.

Jan

Modified Files:
--------------
    slony1-engine/src/backend:
        slony1_funcs.c (r1.21 -> r1.22)

-------------- next part --------------
Index: slony1_funcs.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -Lsrc/backend/slony1_funcs.c -Lsrc/backend/slony1_funcs.c -u -w -r1.21 -r1.22
--- src/backend/slony1_funcs.c
+++ src/backend/slony1_funcs.c
@@ -19,11 +19,14 @@
 #include "executor/spi.h"
 #include "commands/trigger.h"
 #include "commands/async.h"
+#include "catalog/pg_operator.h"
 #include "access/xact.h"
 #include "utils/builtins.h"
 #include "utils/elog.h"
 #ifdef HAVE_TYPCACHE
 #include "utils/typcache.h"
+#else
+#include "parser/parse_oper.h"
 #endif
 #include "mb/pg_wchar.h"
 
@@ -598,30 +601,55 @@
 			 */
 			if (!old_isnull && !new_isnull)
 			{
+				Oid			opr_oid;
+				FmgrInfo   *opr_finfo_p;
+
+				/*
+				 * Lookup the equal operators function call info
+				 * using the typecache if available
+				 */
 #ifdef HAVE_TYPCACHE
 				TypeCacheEntry *type_cache;
 
 				type_cache = lookup_type_cache(
 						SPI_gettypeid(tupdesc, i + 1),
 						TYPECACHE_EQ_OPR | TYPECACHE_EQ_OPR_FINFO);
-				if (DatumGetBool(FunctionCall2(&(type_cache->eq_opr_finfo),
-							old_value, new_value)))
-					continue;
+				opr_oid = type_cache->eq_opr;
+				if (opr_oid == ARRAY_EQ_OP)
+					opr_oid = InvalidOid;
+				else
+					opr_finfo_p = &(type_cache->eq_opr_finfo);
 #else
-				Oid			opr_proc;
 				FmgrInfo	opr_finfo;
 
-				opr_proc = compatible_oper_funcid(makeList1(makeString("=")),
+				opr_oid = compatible_oper_funcid(makeList1(makeString("=")),
 						SPI_gettypeid(tupdesc, i + 1),
 						SPI_gettypeid(tupdesc, i + 1), true);
-				if (!OidIsValid(opr_proc))
-					elog(ERROR, "Slony-I: failed to find '=' operator");
-
-				fmgr_info(opr_proc, &opr_finfo);
-				if (DatumGetBool(FunctionCall2(&opr_finfo,
+				if (OidIsValid(opr_oid))
+				{
+					fmgr_info(opr_oid, &opr_finfo);
+					opr_finfo_p = & opr_finfo;
+				}
+#endif
+				/*
+				 * If we have an equal operator, use that to do binary
+				 * comparision. Else get the string representation of
+				 * both attributes and do string comparision.
+				 */
+				if (OidIsValid(opr_oid))
+				{
+					if (DatumGetBool(FunctionCall2(opr_finfo_p,
 							old_value, new_value)))
 					continue;
-#endif
+				}
+				else
+				{
+					char   *old_strval = SPI_getvalue(old_row, tupdesc, i + 1);
+					char   *new_strval = SPI_getvalue(new_row, tupdesc, i + 1);
+
+					if (strcmp(old_strval, new_strval) == 0)
+						continue;
+				}
 			}
 
 			if (need_comma)


More information about the Slony1-commit mailing list