On 10/09/2014 12:13 AM, Andres Freund wrote:
On 2014-10-08 22:13:46 +0300, Heikki Linnakangas wrote:
As far as I can tell, PostgreSQL's so-called CRC algorithm doesn't
correspond to any bit-by-bit CRC variant and polynomial. My math skills are
not strong enough to determine what the consequences of that are. It might
still be a decent checksum. Or not. I couldn't tell if the good error
detection properties of the normal CRC-32 polynomial apply to our algorithm
or not.

Additional interesting datapoints are that hstore and ltree contain the
same tables - but properly use the reflected computation.

Thoughts?

It clearly seems like a bad idea to continue with this - I don't think
anybody here knows which guarantees this gives us.

The question is how can we move away from this. There's unfortunately
two places that embed PGC32 that are likely to prove problematic when
fixing the algorithm: pg_trgm and tsgist both seem to include crc's in
their logic in a persistent way.  I think we should provide
INIT/COMP/FIN_PG32 using the current algorithm for these.

Agreed, it's not worth breaking pg_upgrade for this.

If we're switching to a saner computation, we should imo also switch to
a better polynom - CRC-32C has better error detection capabilities than
CRC32 and is available in hardware. As we're paying the price pf
breaking compat anyway...

Agreed.

Arguably we could also say that given that there's been little evident
problems with the borked computation we could also switch to a much
faster hash instead of continuing to use crc...

I don't feel like taking the leap. Once we switch to slice-by-4/8 and/or use a hardware instruction when available, CRC is fast enough.

I came up with the attached patches. They do three things:

1. Get rid of the 64-bit CRC code. It's not used for anything, and haven't been for years, so it doesn't seem worth spending any effort to fix them.

2. Switch to CRC-32C (Castagnoli) for WAL and other places that don't need to remain compatible across major versions.

3. Use the same lookup table for hstore and ltree, as used for the legacy "almost CRC-32" algorithm. The tables are identical, so might as well.

Any objections?

- Heikki

>From 4fe6472976f2efc22035e802067a70d3cca61d79 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakan...@iki.fi>
Date: Mon, 27 Oct 2014 12:01:19 +0200
Subject: [PATCH 1/2] Remove support for 64-bit CRC.

It hasn't been used for anything in backend code for a long time.
---
 src/include/utils/pg_crc.h        |  96 ---------
 src/include/utils/pg_crc_tables.h | 416 --------------------------------------
 2 files changed, 512 deletions(-)

diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 375c405..f43f4aa 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -10,9 +10,6 @@
  * We use a normal (not "reflected", in Williams' terms) CRC, using initial
  * all-ones register contents and a final bit inversion.
  *
- * The 64-bit variant is not used as of PostgreSQL 8.1, but we retain the
- * code for possible future use.
- *
  *
  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -56,97 +53,4 @@ do { \
 /* Constant table for CRC calculation */
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
-
-#ifdef PROVIDE_64BIT_CRC
-
-/*
- * If we use a 64-bit integer type, then a 64-bit CRC looks just like the
- * usual sort of implementation.  However, we can also fake it with two
- * 32-bit registers.  Experience has shown that the two-32-bit-registers code
- * is as fast as, or even much faster than, the 64-bit code on all but true
- * 64-bit machines.  We use SIZEOF_VOID_P to check the native word width.
- */
-
-#if SIZEOF_VOID_P < 8
-
-/*
- * crc0 represents the LSBs of the 64-bit value, crc1 the MSBs.  Note that
- * with crc0 placed first, the output of 32-bit and 64-bit implementations
- * will be bit-compatible only on little-endian architectures.  If it were
- * important to make the two possible implementations bit-compatible on
- * all machines, we could do a configure test to decide how to order the
- * two fields, but it seems not worth the trouble.
- */
-typedef struct pg_crc64
-{
-	uint32		crc0;
-	uint32		crc1;
-}	pg_crc64;
-
-/* Initialize a CRC accumulator */
-#define INIT_CRC64(crc) ((crc).crc0 = 0xffffffff, (crc).crc1 = 0xffffffff)
-
-/* Finish a CRC calculation */
-#define FIN_CRC64(crc)	((crc).crc0 ^= 0xffffffff, (crc).crc1 ^= 0xffffffff)
-
-/* Accumulate some (more) bytes into a CRC */
-#define COMP_CRC64(crc, data, len)	\
-do { \
-	uint32		__crc0 = (crc).crc0; \
-	uint32		__crc1 = (crc).crc1; \
-	unsigned char *__data = (unsigned char *) (data); \
-	uint32		__len = (len); \
-\
-	while (__len-- > 0) \
-	{ \
-		int		__tab_index = ((int) (__crc1 >> 24) ^ *__data++) & 0xFF; \
-		__crc1 = pg_crc64_table1[__tab_index] ^ ((__crc1 << 8) | (__crc0 >> 24)); \
-		__crc0 = pg_crc64_table0[__tab_index] ^ (__crc0 << 8); \
-	} \
-	(crc).crc0 = __crc0; \
-	(crc).crc1 = __crc1; \
-} while (0)
-
-/* Check for equality of two CRCs */
-#define EQ_CRC64(c1,c2)  ((c1).crc0 == (c2).crc0 && (c1).crc1 == (c2).crc1)
-
-/* Constant table for CRC calculation */
-extern CRCDLLIMPORT const uint32 pg_crc64_table0[];
-extern CRCDLLIMPORT const uint32 pg_crc64_table1[];
-#else							/* use int64 implementation */
-
-typedef struct pg_crc64
-{
-	uint64		crc0;
-}	pg_crc64;
-
-/* Initialize a CRC accumulator */
-#define INIT_CRC64(crc) ((crc).crc0 = UINT64CONST(0xffffffffffffffff))
-
-/* Finish a CRC calculation */
-#define FIN_CRC64(crc)	((crc).crc0 ^= UINT64CONST(0xffffffffffffffff))
-
-/* Accumulate some (more) bytes into a CRC */
-#define COMP_CRC64(crc, data, len)	\
-do { \
-	uint64		__crc0 = (crc).crc0; \
-	unsigned char *__data = (unsigned char *) (data); \
-	uint32		__len = (len); \
-\
-	while (__len-- > 0) \
-	{ \
-		int		__tab_index = ((int) (__crc0 >> 56) ^ *__data++) & 0xFF; \
-		__crc0 = pg_crc64_table[__tab_index] ^ (__crc0 << 8); \
-	} \
-	(crc).crc0 = __crc0; \
-} while (0)
-
-/* Check for equality of two CRCs */
-#define EQ_CRC64(c1,c2)  ((c1).crc0 == (c2).crc0)
-
-/* Constant table for CRC calculation */
-extern CRCDLLIMPORT const uint64 pg_crc64_table[];
-#endif   /* SIZEOF_VOID_P < 8 */
-#endif   /* PROVIDE_64BIT_CRC */
-
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index a487ee4..f566137 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -14,9 +14,6 @@
  * We use a normal (not "reflected", in Williams' terms) CRC, using initial
  * all-ones register contents and a final bit inversion.
  *
- * The 64-bit variant is not used as of PostgreSQL 8.1, but we retain the
- * code for possible future use.
- *
  *
  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -100,417 +97,4 @@ const uint32 pg_crc32_table[256] = {
 	0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
 };
 
-
-#ifdef PROVIDE_64BIT_CRC
-
-/*
- * This table is based on the polynomial
- *
- * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
- * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
- * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
- * x^7 + x^4 + x + 1
- *
- * which is borrowed from the DLT1 spec
- * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM)
- */
-
-#if SIZEOF_VOID_P < 8			/* this test must match the one in pg_crc.h */
-
-const uint32 pg_crc64_table0[256] = {
-	0x00000000, 0xA9EA3693,
-	0x53D46D26, 0xFA3E5BB5,
-	0x0E42ECDF, 0xA7A8DA4C,
-	0x5D9681F9, 0xF47CB76A,
-	0x1C85D9BE, 0xB56FEF2D,
-	0x4F51B498, 0xE6BB820B,
-	0x12C73561, 0xBB2D03F2,
-	0x41135847, 0xE8F96ED4,
-	0x90E185EF, 0x390BB37C,
-	0xC335E8C9, 0x6ADFDE5A,
-	0x9EA36930, 0x37495FA3,
-	0xCD770416, 0x649D3285,
-	0x8C645C51, 0x258E6AC2,
-	0xDFB03177, 0x765A07E4,
-	0x8226B08E, 0x2BCC861D,
-	0xD1F2DDA8, 0x7818EB3B,
-	0x21C30BDE, 0x88293D4D,
-	0x721766F8, 0xDBFD506B,
-	0x2F81E701, 0x866BD192,
-	0x7C558A27, 0xD5BFBCB4,
-	0x3D46D260, 0x94ACE4F3,
-	0x6E92BF46, 0xC77889D5,
-	0x33043EBF, 0x9AEE082C,
-	0x60D05399, 0xC93A650A,
-	0xB1228E31, 0x18C8B8A2,
-	0xE2F6E317, 0x4B1CD584,
-	0xBF6062EE, 0x168A547D,
-	0xECB40FC8, 0x455E395B,
-	0xADA7578F, 0x044D611C,
-	0xFE733AA9, 0x57990C3A,
-	0xA3E5BB50, 0x0A0F8DC3,
-	0xF031D676, 0x59DBE0E5,
-	0xEA6C212F, 0x438617BC,
-	0xB9B84C09, 0x10527A9A,
-	0xE42ECDF0, 0x4DC4FB63,
-	0xB7FAA0D6, 0x1E109645,
-	0xF6E9F891, 0x5F03CE02,
-	0xA53D95B7, 0x0CD7A324,
-	0xF8AB144E, 0x514122DD,
-	0xAB7F7968, 0x02954FFB,
-	0x7A8DA4C0, 0xD3679253,
-	0x2959C9E6, 0x80B3FF75,
-	0x74CF481F, 0xDD257E8C,
-	0x271B2539, 0x8EF113AA,
-	0x66087D7E, 0xCFE24BED,
-	0x35DC1058, 0x9C3626CB,
-	0x684A91A1, 0xC1A0A732,
-	0x3B9EFC87, 0x9274CA14,
-	0xCBAF2AF1, 0x62451C62,
-	0x987B47D7, 0x31917144,
-	0xC5EDC62E, 0x6C07F0BD,
-	0x9639AB08, 0x3FD39D9B,
-	0xD72AF34F, 0x7EC0C5DC,
-	0x84FE9E69, 0x2D14A8FA,
-	0xD9681F90, 0x70822903,
-	0x8ABC72B6, 0x23564425,
-	0x5B4EAF1E, 0xF2A4998D,
-	0x089AC238, 0xA170F4AB,
-	0x550C43C1, 0xFCE67552,
-	0x06D82EE7, 0xAF321874,
-	0x47CB76A0, 0xEE214033,
-	0x141F1B86, 0xBDF52D15,
-	0x49899A7F, 0xE063ACEC,
-	0x1A5DF759, 0xB3B7C1CA,
-	0x7D3274CD, 0xD4D8425E,
-	0x2EE619EB, 0x870C2F78,
-	0x73709812, 0xDA9AAE81,
-	0x20A4F534, 0x894EC3A7,
-	0x61B7AD73, 0xC85D9BE0,
-	0x3263C055, 0x9B89F6C6,
-	0x6FF541AC, 0xC61F773F,
-	0x3C212C8A, 0x95CB1A19,
-	0xEDD3F122, 0x4439C7B1,
-	0xBE079C04, 0x17EDAA97,
-	0xE3911DFD, 0x4A7B2B6E,
-	0xB04570DB, 0x19AF4648,
-	0xF156289C, 0x58BC1E0F,
-	0xA28245BA, 0x0B687329,
-	0xFF14C443, 0x56FEF2D0,
-	0xACC0A965, 0x052A9FF6,
-	0x5CF17F13, 0xF51B4980,
-	0x0F251235, 0xA6CF24A6,
-	0x52B393CC, 0xFB59A55F,
-	0x0167FEEA, 0xA88DC879,
-	0x4074A6AD, 0xE99E903E,
-	0x13A0CB8B, 0xBA4AFD18,
-	0x4E364A72, 0xE7DC7CE1,
-	0x1DE22754, 0xB40811C7,
-	0xCC10FAFC, 0x65FACC6F,
-	0x9FC497DA, 0x362EA149,
-	0xC2521623, 0x6BB820B0,
-	0x91867B05, 0x386C4D96,
-	0xD0952342, 0x797F15D1,
-	0x83414E64, 0x2AAB78F7,
-	0xDED7CF9D, 0x773DF90E,
-	0x8D03A2BB, 0x24E99428,
-	0x975E55E2, 0x3EB46371,
-	0xC48A38C4, 0x6D600E57,
-	0x991CB93D, 0x30F68FAE,
-	0xCAC8D41B, 0x6322E288,
-	0x8BDB8C5C, 0x2231BACF,
-	0xD80FE17A, 0x71E5D7E9,
-	0x85996083, 0x2C735610,
-	0xD64D0DA5, 0x7FA73B36,
-	0x07BFD00D, 0xAE55E69E,
-	0x546BBD2B, 0xFD818BB8,
-	0x09FD3CD2, 0xA0170A41,
-	0x5A2951F4, 0xF3C36767,
-	0x1B3A09B3, 0xB2D03F20,
-	0x48EE6495, 0xE1045206,
-	0x1578E56C, 0xBC92D3FF,
-	0x46AC884A, 0xEF46BED9,
-	0xB69D5E3C, 0x1F7768AF,
-	0xE549331A, 0x4CA30589,
-	0xB8DFB2E3, 0x11358470,
-	0xEB0BDFC5, 0x42E1E956,
-	0xAA188782, 0x03F2B111,
-	0xF9CCEAA4, 0x5026DC37,
-	0xA45A6B5D, 0x0DB05DCE,
-	0xF78E067B, 0x5E6430E8,
-	0x267CDBD3, 0x8F96ED40,
-	0x75A8B6F5, 0xDC428066,
-	0x283E370C, 0x81D4019F,
-	0x7BEA5A2A, 0xD2006CB9,
-	0x3AF9026D, 0x931334FE,
-	0x692D6F4B, 0xC0C759D8,
-	0x34BBEEB2, 0x9D51D821,
-	0x676F8394, 0xCE85B507
-};
-
-const uint32 pg_crc64_table1[256] = {
-	0x00000000, 0x42F0E1EB,
-	0x85E1C3D7, 0xC711223C,
-	0x49336645, 0x0BC387AE,
-	0xCCD2A592, 0x8E224479,
-	0x9266CC8A, 0xD0962D61,
-	0x17870F5D, 0x5577EEB6,
-	0xDB55AACF, 0x99A54B24,
-	0x5EB46918, 0x1C4488F3,
-	0x663D78FF, 0x24CD9914,
-	0xE3DCBB28, 0xA12C5AC3,
-	0x2F0E1EBA, 0x6DFEFF51,
-	0xAAEFDD6D, 0xE81F3C86,
-	0xF45BB475, 0xB6AB559E,
-	0x71BA77A2, 0x334A9649,
-	0xBD68D230, 0xFF9833DB,
-	0x388911E7, 0x7A79F00C,
-	0xCC7AF1FF, 0x8E8A1014,
-	0x499B3228, 0x0B6BD3C3,
-	0x854997BA, 0xC7B97651,
-	0x00A8546D, 0x4258B586,
-	0x5E1C3D75, 0x1CECDC9E,
-	0xDBFDFEA2, 0x990D1F49,
-	0x172F5B30, 0x55DFBADB,
-	0x92CE98E7, 0xD03E790C,
-	0xAA478900, 0xE8B768EB,
-	0x2FA64AD7, 0x6D56AB3C,
-	0xE374EF45, 0xA1840EAE,
-	0x66952C92, 0x2465CD79,
-	0x3821458A, 0x7AD1A461,
-	0xBDC0865D, 0xFF3067B6,
-	0x711223CF, 0x33E2C224,
-	0xF4F3E018, 0xB60301F3,
-	0xDA050215, 0x98F5E3FE,
-	0x5FE4C1C2, 0x1D142029,
-	0x93366450, 0xD1C685BB,
-	0x16D7A787, 0x5427466C,
-	0x4863CE9F, 0x0A932F74,
-	0xCD820D48, 0x8F72ECA3,
-	0x0150A8DA, 0x43A04931,
-	0x84B16B0D, 0xC6418AE6,
-	0xBC387AEA, 0xFEC89B01,
-	0x39D9B93D, 0x7B2958D6,
-	0xF50B1CAF, 0xB7FBFD44,
-	0x70EADF78, 0x321A3E93,
-	0x2E5EB660, 0x6CAE578B,
-	0xABBF75B7, 0xE94F945C,
-	0x676DD025, 0x259D31CE,
-	0xE28C13F2, 0xA07CF219,
-	0x167FF3EA, 0x548F1201,
-	0x939E303D, 0xD16ED1D6,
-	0x5F4C95AF, 0x1DBC7444,
-	0xDAAD5678, 0x985DB793,
-	0x84193F60, 0xC6E9DE8B,
-	0x01F8FCB7, 0x43081D5C,
-	0xCD2A5925, 0x8FDAB8CE,
-	0x48CB9AF2, 0x0A3B7B19,
-	0x70428B15, 0x32B26AFE,
-	0xF5A348C2, 0xB753A929,
-	0x3971ED50, 0x7B810CBB,
-	0xBC902E87, 0xFE60CF6C,
-	0xE224479F, 0xA0D4A674,
-	0x67C58448, 0x253565A3,
-	0xAB1721DA, 0xE9E7C031,
-	0x2EF6E20D, 0x6C0603E6,
-	0xF6FAE5C0, 0xB40A042B,
-	0x731B2617, 0x31EBC7FC,
-	0xBFC98385, 0xFD39626E,
-	0x3A284052, 0x78D8A1B9,
-	0x649C294A, 0x266CC8A1,
-	0xE17DEA9D, 0xA38D0B76,
-	0x2DAF4F0F, 0x6F5FAEE4,
-	0xA84E8CD8, 0xEABE6D33,
-	0x90C79D3F, 0xD2377CD4,
-	0x15265EE8, 0x57D6BF03,
-	0xD9F4FB7A, 0x9B041A91,
-	0x5C1538AD, 0x1EE5D946,
-	0x02A151B5, 0x4051B05E,
-	0x87409262, 0xC5B07389,
-	0x4B9237F0, 0x0962D61B,
-	0xCE73F427, 0x8C8315CC,
-	0x3A80143F, 0x7870F5D4,
-	0xBF61D7E8, 0xFD913603,
-	0x73B3727A, 0x31439391,
-	0xF652B1AD, 0xB4A25046,
-	0xA8E6D8B5, 0xEA16395E,
-	0x2D071B62, 0x6FF7FA89,
-	0xE1D5BEF0, 0xA3255F1B,
-	0x64347D27, 0x26C49CCC,
-	0x5CBD6CC0, 0x1E4D8D2B,
-	0xD95CAF17, 0x9BAC4EFC,
-	0x158E0A85, 0x577EEB6E,
-	0x906FC952, 0xD29F28B9,
-	0xCEDBA04A, 0x8C2B41A1,
-	0x4B3A639D, 0x09CA8276,
-	0x87E8C60F, 0xC51827E4,
-	0x020905D8, 0x40F9E433,
-	0x2CFFE7D5, 0x6E0F063E,
-	0xA91E2402, 0xEBEEC5E9,
-	0x65CC8190, 0x273C607B,
-	0xE02D4247, 0xA2DDA3AC,
-	0xBE992B5F, 0xFC69CAB4,
-	0x3B78E888, 0x79880963,
-	0xF7AA4D1A, 0xB55AACF1,
-	0x724B8ECD, 0x30BB6F26,
-	0x4AC29F2A, 0x08327EC1,
-	0xCF235CFD, 0x8DD3BD16,
-	0x03F1F96F, 0x41011884,
-	0x86103AB8, 0xC4E0DB53,
-	0xD8A453A0, 0x9A54B24B,
-	0x5D459077, 0x1FB5719C,
-	0x919735E5, 0xD367D40E,
-	0x1476F632, 0x568617D9,
-	0xE085162A, 0xA275F7C1,
-	0x6564D5FD, 0x27943416,
-	0xA9B6706F, 0xEB469184,
-	0x2C57B3B8, 0x6EA75253,
-	0x72E3DAA0, 0x30133B4B,
-	0xF7021977, 0xB5F2F89C,
-	0x3BD0BCE5, 0x79205D0E,
-	0xBE317F32, 0xFCC19ED9,
-	0x86B86ED5, 0xC4488F3E,
-	0x0359AD02, 0x41A94CE9,
-	0xCF8B0890, 0x8D7BE97B,
-	0x4A6ACB47, 0x089A2AAC,
-	0x14DEA25F, 0x562E43B4,
-	0x913F6188, 0xD3CF8063,
-	0x5DEDC41A, 0x1F1D25F1,
-	0xD80C07CD, 0x9AFCE626
-};
-#else							/* use int64 implementation */
-
-const uint64 pg_crc64_table[256] = {
-	UINT64CONST(0x0000000000000000), UINT64CONST(0x42F0E1EBA9EA3693),
-	UINT64CONST(0x85E1C3D753D46D26), UINT64CONST(0xC711223CFA3E5BB5),
-	UINT64CONST(0x493366450E42ECDF), UINT64CONST(0x0BC387AEA7A8DA4C),
-	UINT64CONST(0xCCD2A5925D9681F9), UINT64CONST(0x8E224479F47CB76A),
-	UINT64CONST(0x9266CC8A1C85D9BE), UINT64CONST(0xD0962D61B56FEF2D),
-	UINT64CONST(0x17870F5D4F51B498), UINT64CONST(0x5577EEB6E6BB820B),
-	UINT64CONST(0xDB55AACF12C73561), UINT64CONST(0x99A54B24BB2D03F2),
-	UINT64CONST(0x5EB4691841135847), UINT64CONST(0x1C4488F3E8F96ED4),
-	UINT64CONST(0x663D78FF90E185EF), UINT64CONST(0x24CD9914390BB37C),
-	UINT64CONST(0xE3DCBB28C335E8C9), UINT64CONST(0xA12C5AC36ADFDE5A),
-	UINT64CONST(0x2F0E1EBA9EA36930), UINT64CONST(0x6DFEFF5137495FA3),
-	UINT64CONST(0xAAEFDD6DCD770416), UINT64CONST(0xE81F3C86649D3285),
-	UINT64CONST(0xF45BB4758C645C51), UINT64CONST(0xB6AB559E258E6AC2),
-	UINT64CONST(0x71BA77A2DFB03177), UINT64CONST(0x334A9649765A07E4),
-	UINT64CONST(0xBD68D2308226B08E), UINT64CONST(0xFF9833DB2BCC861D),
-	UINT64CONST(0x388911E7D1F2DDA8), UINT64CONST(0x7A79F00C7818EB3B),
-	UINT64CONST(0xCC7AF1FF21C30BDE), UINT64CONST(0x8E8A101488293D4D),
-	UINT64CONST(0x499B3228721766F8), UINT64CONST(0x0B6BD3C3DBFD506B),
-	UINT64CONST(0x854997BA2F81E701), UINT64CONST(0xC7B97651866BD192),
-	UINT64CONST(0x00A8546D7C558A27), UINT64CONST(0x4258B586D5BFBCB4),
-	UINT64CONST(0x5E1C3D753D46D260), UINT64CONST(0x1CECDC9E94ACE4F3),
-	UINT64CONST(0xDBFDFEA26E92BF46), UINT64CONST(0x990D1F49C77889D5),
-	UINT64CONST(0x172F5B3033043EBF), UINT64CONST(0x55DFBADB9AEE082C),
-	UINT64CONST(0x92CE98E760D05399), UINT64CONST(0xD03E790CC93A650A),
-	UINT64CONST(0xAA478900B1228E31), UINT64CONST(0xE8B768EB18C8B8A2),
-	UINT64CONST(0x2FA64AD7E2F6E317), UINT64CONST(0x6D56AB3C4B1CD584),
-	UINT64CONST(0xE374EF45BF6062EE), UINT64CONST(0xA1840EAE168A547D),
-	UINT64CONST(0x66952C92ECB40FC8), UINT64CONST(0x2465CD79455E395B),
-	UINT64CONST(0x3821458AADA7578F), UINT64CONST(0x7AD1A461044D611C),
-	UINT64CONST(0xBDC0865DFE733AA9), UINT64CONST(0xFF3067B657990C3A),
-	UINT64CONST(0x711223CFA3E5BB50), UINT64CONST(0x33E2C2240A0F8DC3),
-	UINT64CONST(0xF4F3E018F031D676), UINT64CONST(0xB60301F359DBE0E5),
-	UINT64CONST(0xDA050215EA6C212F), UINT64CONST(0x98F5E3FE438617BC),
-	UINT64CONST(0x5FE4C1C2B9B84C09), UINT64CONST(0x1D14202910527A9A),
-	UINT64CONST(0x93366450E42ECDF0), UINT64CONST(0xD1C685BB4DC4FB63),
-	UINT64CONST(0x16D7A787B7FAA0D6), UINT64CONST(0x5427466C1E109645),
-	UINT64CONST(0x4863CE9FF6E9F891), UINT64CONST(0x0A932F745F03CE02),
-	UINT64CONST(0xCD820D48A53D95B7), UINT64CONST(0x8F72ECA30CD7A324),
-	UINT64CONST(0x0150A8DAF8AB144E), UINT64CONST(0x43A04931514122DD),
-	UINT64CONST(0x84B16B0DAB7F7968), UINT64CONST(0xC6418AE602954FFB),
-	UINT64CONST(0xBC387AEA7A8DA4C0), UINT64CONST(0xFEC89B01D3679253),
-	UINT64CONST(0x39D9B93D2959C9E6), UINT64CONST(0x7B2958D680B3FF75),
-	UINT64CONST(0xF50B1CAF74CF481F), UINT64CONST(0xB7FBFD44DD257E8C),
-	UINT64CONST(0x70EADF78271B2539), UINT64CONST(0x321A3E938EF113AA),
-	UINT64CONST(0x2E5EB66066087D7E), UINT64CONST(0x6CAE578BCFE24BED),
-	UINT64CONST(0xABBF75B735DC1058), UINT64CONST(0xE94F945C9C3626CB),
-	UINT64CONST(0x676DD025684A91A1), UINT64CONST(0x259D31CEC1A0A732),
-	UINT64CONST(0xE28C13F23B9EFC87), UINT64CONST(0xA07CF2199274CA14),
-	UINT64CONST(0x167FF3EACBAF2AF1), UINT64CONST(0x548F120162451C62),
-	UINT64CONST(0x939E303D987B47D7), UINT64CONST(0xD16ED1D631917144),
-	UINT64CONST(0x5F4C95AFC5EDC62E), UINT64CONST(0x1DBC74446C07F0BD),
-	UINT64CONST(0xDAAD56789639AB08), UINT64CONST(0x985DB7933FD39D9B),
-	UINT64CONST(0x84193F60D72AF34F), UINT64CONST(0xC6E9DE8B7EC0C5DC),
-	UINT64CONST(0x01F8FCB784FE9E69), UINT64CONST(0x43081D5C2D14A8FA),
-	UINT64CONST(0xCD2A5925D9681F90), UINT64CONST(0x8FDAB8CE70822903),
-	UINT64CONST(0x48CB9AF28ABC72B6), UINT64CONST(0x0A3B7B1923564425),
-	UINT64CONST(0x70428B155B4EAF1E), UINT64CONST(0x32B26AFEF2A4998D),
-	UINT64CONST(0xF5A348C2089AC238), UINT64CONST(0xB753A929A170F4AB),
-	UINT64CONST(0x3971ED50550C43C1), UINT64CONST(0x7B810CBBFCE67552),
-	UINT64CONST(0xBC902E8706D82EE7), UINT64CONST(0xFE60CF6CAF321874),
-	UINT64CONST(0xE224479F47CB76A0), UINT64CONST(0xA0D4A674EE214033),
-	UINT64CONST(0x67C58448141F1B86), UINT64CONST(0x253565A3BDF52D15),
-	UINT64CONST(0xAB1721DA49899A7F), UINT64CONST(0xE9E7C031E063ACEC),
-	UINT64CONST(0x2EF6E20D1A5DF759), UINT64CONST(0x6C0603E6B3B7C1CA),
-	UINT64CONST(0xF6FAE5C07D3274CD), UINT64CONST(0xB40A042BD4D8425E),
-	UINT64CONST(0x731B26172EE619EB), UINT64CONST(0x31EBC7FC870C2F78),
-	UINT64CONST(0xBFC9838573709812), UINT64CONST(0xFD39626EDA9AAE81),
-	UINT64CONST(0x3A28405220A4F534), UINT64CONST(0x78D8A1B9894EC3A7),
-	UINT64CONST(0x649C294A61B7AD73), UINT64CONST(0x266CC8A1C85D9BE0),
-	UINT64CONST(0xE17DEA9D3263C055), UINT64CONST(0xA38D0B769B89F6C6),
-	UINT64CONST(0x2DAF4F0F6FF541AC), UINT64CONST(0x6F5FAEE4C61F773F),
-	UINT64CONST(0xA84E8CD83C212C8A), UINT64CONST(0xEABE6D3395CB1A19),
-	UINT64CONST(0x90C79D3FEDD3F122), UINT64CONST(0xD2377CD44439C7B1),
-	UINT64CONST(0x15265EE8BE079C04), UINT64CONST(0x57D6BF0317EDAA97),
-	UINT64CONST(0xD9F4FB7AE3911DFD), UINT64CONST(0x9B041A914A7B2B6E),
-	UINT64CONST(0x5C1538ADB04570DB), UINT64CONST(0x1EE5D94619AF4648),
-	UINT64CONST(0x02A151B5F156289C), UINT64CONST(0x4051B05E58BC1E0F),
-	UINT64CONST(0x87409262A28245BA), UINT64CONST(0xC5B073890B687329),
-	UINT64CONST(0x4B9237F0FF14C443), UINT64CONST(0x0962D61B56FEF2D0),
-	UINT64CONST(0xCE73F427ACC0A965), UINT64CONST(0x8C8315CC052A9FF6),
-	UINT64CONST(0x3A80143F5CF17F13), UINT64CONST(0x7870F5D4F51B4980),
-	UINT64CONST(0xBF61D7E80F251235), UINT64CONST(0xFD913603A6CF24A6),
-	UINT64CONST(0x73B3727A52B393CC), UINT64CONST(0x31439391FB59A55F),
-	UINT64CONST(0xF652B1AD0167FEEA), UINT64CONST(0xB4A25046A88DC879),
-	UINT64CONST(0xA8E6D8B54074A6AD), UINT64CONST(0xEA16395EE99E903E),
-	UINT64CONST(0x2D071B6213A0CB8B), UINT64CONST(0x6FF7FA89BA4AFD18),
-	UINT64CONST(0xE1D5BEF04E364A72), UINT64CONST(0xA3255F1BE7DC7CE1),
-	UINT64CONST(0x64347D271DE22754), UINT64CONST(0x26C49CCCB40811C7),
-	UINT64CONST(0x5CBD6CC0CC10FAFC), UINT64CONST(0x1E4D8D2B65FACC6F),
-	UINT64CONST(0xD95CAF179FC497DA), UINT64CONST(0x9BAC4EFC362EA149),
-	UINT64CONST(0x158E0A85C2521623), UINT64CONST(0x577EEB6E6BB820B0),
-	UINT64CONST(0x906FC95291867B05), UINT64CONST(0xD29F28B9386C4D96),
-	UINT64CONST(0xCEDBA04AD0952342), UINT64CONST(0x8C2B41A1797F15D1),
-	UINT64CONST(0x4B3A639D83414E64), UINT64CONST(0x09CA82762AAB78F7),
-	UINT64CONST(0x87E8C60FDED7CF9D), UINT64CONST(0xC51827E4773DF90E),
-	UINT64CONST(0x020905D88D03A2BB), UINT64CONST(0x40F9E43324E99428),
-	UINT64CONST(0x2CFFE7D5975E55E2), UINT64CONST(0x6E0F063E3EB46371),
-	UINT64CONST(0xA91E2402C48A38C4), UINT64CONST(0xEBEEC5E96D600E57),
-	UINT64CONST(0x65CC8190991CB93D), UINT64CONST(0x273C607B30F68FAE),
-	UINT64CONST(0xE02D4247CAC8D41B), UINT64CONST(0xA2DDA3AC6322E288),
-	UINT64CONST(0xBE992B5F8BDB8C5C), UINT64CONST(0xFC69CAB42231BACF),
-	UINT64CONST(0x3B78E888D80FE17A), UINT64CONST(0x7988096371E5D7E9),
-	UINT64CONST(0xF7AA4D1A85996083), UINT64CONST(0xB55AACF12C735610),
-	UINT64CONST(0x724B8ECDD64D0DA5), UINT64CONST(0x30BB6F267FA73B36),
-	UINT64CONST(0x4AC29F2A07BFD00D), UINT64CONST(0x08327EC1AE55E69E),
-	UINT64CONST(0xCF235CFD546BBD2B), UINT64CONST(0x8DD3BD16FD818BB8),
-	UINT64CONST(0x03F1F96F09FD3CD2), UINT64CONST(0x41011884A0170A41),
-	UINT64CONST(0x86103AB85A2951F4), UINT64CONST(0xC4E0DB53F3C36767),
-	UINT64CONST(0xD8A453A01B3A09B3), UINT64CONST(0x9A54B24BB2D03F20),
-	UINT64CONST(0x5D45907748EE6495), UINT64CONST(0x1FB5719CE1045206),
-	UINT64CONST(0x919735E51578E56C), UINT64CONST(0xD367D40EBC92D3FF),
-	UINT64CONST(0x1476F63246AC884A), UINT64CONST(0x568617D9EF46BED9),
-	UINT64CONST(0xE085162AB69D5E3C), UINT64CONST(0xA275F7C11F7768AF),
-	UINT64CONST(0x6564D5FDE549331A), UINT64CONST(0x279434164CA30589),
-	UINT64CONST(0xA9B6706FB8DFB2E3), UINT64CONST(0xEB46918411358470),
-	UINT64CONST(0x2C57B3B8EB0BDFC5), UINT64CONST(0x6EA7525342E1E956),
-	UINT64CONST(0x72E3DAA0AA188782), UINT64CONST(0x30133B4B03F2B111),
-	UINT64CONST(0xF7021977F9CCEAA4), UINT64CONST(0xB5F2F89C5026DC37),
-	UINT64CONST(0x3BD0BCE5A45A6B5D), UINT64CONST(0x79205D0E0DB05DCE),
-	UINT64CONST(0xBE317F32F78E067B), UINT64CONST(0xFCC19ED95E6430E8),
-	UINT64CONST(0x86B86ED5267CDBD3), UINT64CONST(0xC4488F3E8F96ED40),
-	UINT64CONST(0x0359AD0275A8B6F5), UINT64CONST(0x41A94CE9DC428066),
-	UINT64CONST(0xCF8B0890283E370C), UINT64CONST(0x8D7BE97B81D4019F),
-	UINT64CONST(0x4A6ACB477BEA5A2A), UINT64CONST(0x089A2AACD2006CB9),
-	UINT64CONST(0x14DEA25F3AF9026D), UINT64CONST(0x562E43B4931334FE),
-	UINT64CONST(0x913F6188692D6F4B), UINT64CONST(0xD3CF8063C0C759D8),
-	UINT64CONST(0x5DEDC41A34BBEEB2), UINT64CONST(0x1F1D25F19D51D821),
-	UINT64CONST(0xD80C07CD676F8394), UINT64CONST(0x9AFCE626CE85B507)
-};
-#endif   /* SIZEOF_VOID_P < 8 */
-#endif   /* PROVIDE_64BIT_CRC */
-
 #endif   /* PG_CRC_TABLES_H */
-- 
2.1.1

>From d7718f2f180d6f67181dc13e5d9341ad856e9ada Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakan...@iki.fi>
Date: Mon, 27 Oct 2014 15:31:59 +0200
Subject: [PATCH 2/2] Switch to CRC-32C in WAL and other places.

The old algorithm was found to not be the usual CRC-32 algorithm, used by
Ethernet et al. We were using a non-reflected lookup table with code meant
for a reflected lookup table. That's a strange combination that AFAICS does
not correspond to any bit-wise CRC calculation, which makes it difficult to
reason about its properties. Although it has worked well in practice, seems
safer to use a well-known algorithm.

Since we're changing the algorithm anyway, we might as well choose a
different polynomial. The Castagnoli polynomial has better error-correcting
properties than the traditional CRC-32 polynomial (even if we had
implemented it correctly). Another reason for picking that is that some new
CPUs have hardware support for calculating CRC-32C, but not CRC-32, let
alone our strange variant of it. This patch doesn't add any support for such
hardware, but a future patch now could do that.

The old algorithm is kept around for tsquery and pg_trgm, which use the
values in indexes that need to remain compatible so that pg_upgrade works.

While we're at it, share the lookup table for CRC-32 calculation between
hstore, ltree and core. They all use the same table, so might as well.
---
 contrib/hstore/Makefile                     |   2 +-
 contrib/hstore/crc32.c                      | 106 --------------------------
 contrib/hstore/crc32.h                      |  13 ----
 contrib/hstore/hstore_gist.c                |  16 +++-
 contrib/ltree/Makefile                      |   2 +-
 contrib/ltree/_ltree_gist.c                 |  19 +++--
 contrib/ltree/crc32.c                       | 114 ----------------------------
 contrib/ltree/crc32.h                       |  12 ---
 contrib/ltree/ltree_gist.c                  |  12 ++-
 contrib/ltree/ltree_io.c                    |  11 ++-
 contrib/ltree/ltxtquery_io.c                |  10 ++-
 contrib/pg_trgm/trgm_op.c                   |   6 +-
 src/backend/access/transam/twophase.c       |  24 +++---
 src/backend/access/transam/xlog.c           |  50 ++++++------
 src/backend/access/transam/xlogreader.c     |  12 +--
 src/backend/replication/logical/snapbuild.c |  28 +++----
 src/backend/replication/slot.c              |  20 ++---
 src/backend/utils/adt/tsgistidx.c           |   6 +-
 src/backend/utils/adt/tsquery.c             |  12 +--
 src/backend/utils/cache/relmapper.c         |  16 ++--
 src/bin/pg_controldata/pg_controldata.c     |  12 +--
 src/bin/pg_resetxlog/pg_resetxlog.c         |  30 ++++----
 src/include/utils/pg_crc.h                  |  92 ++++++++++++++++++----
 src/include/utils/pg_crc_tables.h           |  73 ++++++++++++++++++
 24 files changed, 313 insertions(+), 385 deletions(-)
 delete mode 100644 contrib/hstore/crc32.c
 delete mode 100644 contrib/hstore/crc32.h
 delete mode 100644 contrib/ltree/crc32.c
 delete mode 100644 contrib/ltree/crc32.h

diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile
index 3193668..82908de 100644
--- a/contrib/hstore/Makefile
+++ b/contrib/hstore/Makefile
@@ -2,7 +2,7 @@
 
 MODULE_big = hstore
 OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \
-	crc32.o $(WIN32RES)
+	$(WIN32RES)
 
 EXTENSION = hstore
 DATA = hstore--1.3.sql hstore--1.2--1.3.sql \
diff --git a/contrib/hstore/crc32.c b/contrib/hstore/crc32.c
deleted file mode 100644
index c82fc66..0000000
--- a/contrib/hstore/crc32.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * contrib/hstore/crc32.c
- *
- * Both POSIX and CRC32 checksums */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "crc32.h"
-
-/*
- * This code implements the AUTODIN II polynomial
- * The variable corresponding to the macro argument "crc" should
- * be an unsigned long.
- * Original code  by Spencer Garrett <s...@quick.com>
- */
-
-#define _CRC32_(crc, ch)	 (crc = (crc >> 8) ^ crc32tab[(crc ^ (ch)) & 0xff])
-
-/* generated using the AUTODIN II polynomial
- *	x^32 + x^26 + x^23 + x^22 + x^16 +
- *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
- */
-
-static const unsigned int crc32tab[256] = {
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-unsigned int
-crc32_sz(char *buf, int size)
-{
-	unsigned int crc = ~((unsigned int) 0);
-	char	   *p;
-	int			len,
-				nr;
-
-	len = 0;
-	nr = size;
-	for (len += nr, p = buf; nr--; ++p)
-		_CRC32_(crc, *p);
-	return ~crc;
-}
diff --git a/contrib/hstore/crc32.h b/contrib/hstore/crc32.h
deleted file mode 100644
index f5bfd82..0000000
--- a/contrib/hstore/crc32.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * contrib/hstore/crc32.h
- */
-#ifndef _CRC32_H
-#define _CRC32_H
-
-/* Returns crc32 of data block */
-extern unsigned int crc32_sz(char *buf, int size);
-
-/* Returns crc32 of null-terminated string */
-#define crc32(buf) crc32_sz((buf),strlen(buf))
-
-#endif
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index d4a9aaa..876b435 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -6,8 +6,8 @@
 #include "access/gist.h"
 #include "access/skey.h"
 #include "catalog/pg_type.h"
+#include "utils/pg_crc.h"
 
-#include "crc32.h"
 #include "hstore.h"
 
 /* bigint defines */
@@ -68,6 +68,20 @@ typedef struct
 
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
 
+/* shorthand for calculating CRC-32 of a single chunk of data. */
+static pg_crc32
+crc32_sz(char *buf, int size)
+{
+	pg_crc32 crc;
+
+	INIT_TRADITIONAL_CRC32(crc);
+	COMP_TRADITIONAL_CRC32(crc, buf, size);
+	FIN_TRADITIONAL_CRC32(crc);
+
+	return crc;
+}
+
+
 PG_FUNCTION_INFO_V1(ghstore_in);
 PG_FUNCTION_INFO_V1(ghstore_out);
 
diff --git a/contrib/ltree/Makefile b/contrib/ltree/Makefile
index a41e457..d7604d6 100644
--- a/contrib/ltree/Makefile
+++ b/contrib/ltree/Makefile
@@ -1,7 +1,7 @@
 # contrib/ltree/Makefile
 
 MODULE_big = ltree
-OBJS = 	ltree_io.o ltree_op.o lquery_op.o _ltree_op.o crc32.o \
+OBJS = 	ltree_io.o ltree_op.o lquery_op.o _ltree_op.o \
 	ltxtquery_io.o ltxtquery_op.o ltree_gist.o _ltree_gist.o $(WIN32RES)
 PG_CPPFLAGS = -DLOWER_NODE
 
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 41be68d..64fb173 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -9,7 +9,7 @@
 
 #include "access/gist.h"
 #include "access/skey.h"
-#include "crc32.h"
+#include "utils/pg_crc.h"
 #include "ltree.h"
 
 
@@ -51,12 +51,14 @@ hashing(BITVECP sign, ltree *t)
 {
 	int			tlen = t->numlevel;
 	ltree_level *cur = LTREE_FIRST(t);
-	int			hash;
+	pg_crc32	crc;
 
 	while (tlen > 0)
 	{
-		hash = ltree_crc32_sz(cur->name, cur->len);
-		AHASH(sign, hash);
+		INIT_TRADITIONAL_CRC32(crc);
+		COMP_TRADITIONAL_CRC32(crc, cur->name, cur->len);
+		FIN_TRADITIONAL_CRC32(crc);
+		AHASH(sign, crc);
 		cur = LEVEL_NEXT(cur);
 		tlen--;
 	}
@@ -441,15 +443,18 @@ gist_te(ltree_gist *key, ltree *query)
 	ltree_level *curq = LTREE_FIRST(query);
 	BITVECP		sign = LTG_SIGN(key);
 	int			qlen = query->numlevel;
-	unsigned int hv;
+	pg_crc32	crc;
 
 	if (LTG_ISALLTRUE(key))
 		return true;
 
 	while (qlen > 0)
 	{
-		hv = ltree_crc32_sz(curq->name, curq->len);
-		if (!GETBIT(sign, AHASHVAL(hv)))
+		INIT_TRADITIONAL_CRC32(crc);
+		COMP_TRADITIONAL_CRC32(crc, curq->name, curq->len);
+		FIN_TRADITIONAL_CRC32(crc);
+
+		if (!GETBIT(sign, AHASHVAL(crc)))
 			return false;
 		curq = LEVEL_NEXT(curq);
 		qlen--;
diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c
deleted file mode 100644
index ea1a661..0000000
--- a/contrib/ltree/crc32.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Both POSIX and CRC32 checksums */
-
-/* contrib/ltree/crc32.c */
-
-#include "postgres.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#ifdef LOWER_NODE
-#include <ctype.h>
-#define TOLOWER(x)	tolower((unsigned char) (x))
-#else
-#define TOLOWER(x)	(x)
-#endif
-
-#include "crc32.h"
-
-/*
- * This code implements the AUTODIN II polynomial
- * The variable corresponding to the macro argument "crc" should
- * be an unsigned long.
- * Oroginal code  by Spencer Garrett <s...@quick.com>
- */
-
-#define _CRC32_(crc, ch)	 ((crc) = ((crc) >> 8) ^ crc32tab[((crc) ^ (ch)) & 0xff])
-
-/* generated using the AUTODIN II polynomial
- *	x^32 + x^26 + x^23 + x^22 + x^16 +
- *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
- */
-
-static const unsigned int crc32tab[256] = {
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-unsigned int
-ltree_crc32_sz(char *buf, int size)
-{
-	unsigned int crc = ~((unsigned int) 0);
-	char	   *p;
-	int			len,
-				nr;
-
-	len = 0;
-	nr = size;
-	for (len += nr, p = buf; nr--; ++p)
-		_CRC32_(crc, TOLOWER((unsigned int) *p));
-	return ~crc;
-}
diff --git a/contrib/ltree/crc32.h b/contrib/ltree/crc32.h
deleted file mode 100644
index 269d05d..0000000
--- a/contrib/ltree/crc32.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _CRC32_H
-#define _CRC32_H
-
-/* contrib/ltree/crc32.h */
-
-/* Returns crc32 of data block */
-extern unsigned int ltree_crc32_sz(char *buf, int size);
-
-/* Returns crc32 of null-terminated string */
-#define crc32(buf) ltree_crc32_sz((buf),strlen(buf))
-
-#endif
diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c
index 2d89f1a..91c5081 100644
--- a/contrib/ltree/ltree_gist.c
+++ b/contrib/ltree/ltree_gist.c
@@ -7,7 +7,7 @@
 
 #include "access/gist.h"
 #include "access/skey.h"
-#include "crc32.h"
+#include "utils/pg_crc.h"
 #include "ltree.h"
 
 #define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
@@ -136,12 +136,16 @@ hashing(BITVECP sign, ltree *t)
 {
 	int			tlen = t->numlevel;
 	ltree_level *cur = LTREE_FIRST(t);
-	int			hash;
 
 	while (tlen > 0)
 	{
-		hash = ltree_crc32_sz(cur->name, cur->len);
-		HASH(sign, hash);
+		pg_crc32 crc;
+
+		INIT_TRADITIONAL_CRC32(crc);
+		COMP_TRADITIONAL_CRC32(crc, cur->name, cur->len);
+		FIN_TRADITIONAL_CRC32(crc);
+
+		HASH(sign, crc);
 		cur = LEVEL_NEXT(cur);
 		tlen--;
 	}
diff --git a/contrib/ltree/ltree_io.c b/contrib/ltree/ltree_io.c
index a1d4a0d..80b507a 100644
--- a/contrib/ltree/ltree_io.c
+++ b/contrib/ltree/ltree_io.c
@@ -9,7 +9,7 @@
 
 #include "ltree.h"
 #include "utils/memutils.h"
-#include "crc32.h"
+#include "utils/pg_crc.h"
 
 PG_FUNCTION_INFO_V1(ltree_in);
 PG_FUNCTION_INFO_V1(ltree_out);
@@ -494,10 +494,17 @@ lquery_in(PG_FUNCTION_ARGS)
 			lptr = GETVAR(curqlevel);
 			while (lptr - GETVAR(curqlevel) < curqlevel->numvar)
 			{
+				pg_crc32 crc;
+
 				cur->totallen += MAXALIGN(LVAR_HDRSIZE + lptr->len);
 				lrptr->len = lptr->len;
 				lrptr->flag = lptr->flag;
-				lrptr->val = ltree_crc32_sz(lptr->start, lptr->len);
+
+				INIT_CRC32(crc);
+				COMP_CRC32(crc, lptr->start, lptr->len);
+				FIN_CRC32(crc);
+				lrptr->val = crc;
+
 				memcpy(lrptr->name, lptr->start, lptr->len);
 				lptr++;
 				lrptr = LVAR_NEXT(lrptr);
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index ddc63d7..26b24d9 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -7,7 +7,7 @@
 
 #include <ctype.h>
 
-#include "crc32.h"
+#include "utils/pg_crc.h"
 #include "ltree.h"
 #include "miscadmin.h"
 
@@ -171,12 +171,18 @@ pushquery(QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval
 static void
 pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
 {
+	pg_crc32	crc;
+
 	if (lenval > 0xffff)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("word is too long")));
 
-	pushquery(state, type, ltree_crc32_sz(strval, lenval),
+	INIT_CRC32(crc);
+	COMP_CRC32(crc, strval, lenval);
+	FIN_CRC32(crc);
+
+	pushquery(state, type, crc,
 			  state->curop - state->op, lenval, flag);
 
 	while (state->curop - state->op + lenval + 1 >= state->lenop)
diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c
index df15b52..5ec7f26 100644
--- a/contrib/pg_trgm/trgm_op.c
+++ b/contrib/pg_trgm/trgm_op.c
@@ -108,9 +108,9 @@ compact_trigram(trgm *tptr, char *str, int bytelen)
 	{
 		pg_crc32	crc;
 
-		INIT_CRC32(crc);
-		COMP_CRC32(crc, str, bytelen);
-		FIN_CRC32(crc);
+		INIT_LEGACY_CRC32(crc);
+		COMP_LEGACY_CRC32(crc, str, bytelen);
+		FIN_LEGACY_CRC32(crc);
 
 		/*
 		 * use only 3 upper bytes from crc, hope, it's good enough hashing
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index d5409a6..c4069c3 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -847,9 +847,9 @@ TwoPhaseGetDummyProc(TransactionId xid)
  *	6. TwoPhaseRecordOnDisk
  *	7. ...
  *	8. TwoPhaseRecordOnDisk (end sentinel, rmid == TWOPHASE_RM_END_ID)
- *	9. CRC32
+ *	9. checksum (CRC-32C)
  *
- * Each segment except the final CRC32 is MAXALIGN'd.
+ * Each segment except the final checksum is MAXALIGN'd.
  */
 
 /*
@@ -1056,11 +1056,11 @@ EndPrepare(GlobalTransaction gxact)
 						path)));
 
 	/* Write data to file, and calculate CRC as we pass over it */
-	INIT_CRC32(statefile_crc);
+	INIT_CRC32C(statefile_crc);
 
 	for (record = records.head; record != NULL; record = record->next)
 	{
-		COMP_CRC32(statefile_crc, record->data, record->len);
+		COMP_CRC32C(statefile_crc, record->data, record->len);
 		if ((write(fd, record->data, record->len)) != record->len)
 		{
 			CloseTransientFile(fd);
@@ -1070,7 +1070,7 @@ EndPrepare(GlobalTransaction gxact)
 		}
 	}
 
-	FIN_CRC32(statefile_crc);
+	FIN_CRC32C(statefile_crc);
 
 	/*
 	 * Write a deliberately bogus CRC to the state file; this is just paranoia
@@ -1289,13 +1289,13 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings)
 		return NULL;
 	}
 
-	INIT_CRC32(calc_crc);
-	COMP_CRC32(calc_crc, buf, crc_offset);
-	FIN_CRC32(calc_crc);
+	INIT_CRC32C(calc_crc);
+	COMP_CRC32C(calc_crc, buf, crc_offset);
+	FIN_CRC32C(calc_crc);
 
 	file_crc = *((pg_crc32 *) (buf + crc_offset));
 
-	if (!EQ_CRC32(calc_crc, file_crc))
+	if (!EQ_CRC32C(calc_crc, file_crc))
 	{
 		pfree(buf);
 		return NULL;
@@ -1540,9 +1540,9 @@ RecreateTwoPhaseFile(TransactionId xid, void *content, int len)
 	int			fd;
 
 	/* Recompute CRC */
-	INIT_CRC32(statefile_crc);
-	COMP_CRC32(statefile_crc, content, len);
-	FIN_CRC32(statefile_crc);
+	INIT_CRC32C(statefile_crc);
+	COMP_CRC32C(statefile_crc, content, len);
+	FIN_CRC32C(statefile_crc);
 
 	TwoPhaseFilePath(path, xid);
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 3c9aeae..3160db7 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -1059,9 +1059,9 @@ begin:;
 	 * the whole record in the order: rdata, then backup blocks, then record
 	 * header.
 	 */
-	INIT_CRC32(rdata_crc);
+	INIT_CRC32C(rdata_crc);
 	for (rdt = rdata; rdt != NULL; rdt = rdt->next)
-		COMP_CRC32(rdata_crc, rdt->data, rdt->len);
+		COMP_CRC32C(rdata_crc, rdt->data, rdt->len);
 
 	/*
 	 * Construct record header (prev-link is filled in later, after reserving
@@ -1076,7 +1076,7 @@ begin:;
 	rechdr->xl_info = info;
 	rechdr->xl_rmid = rmid;
 	rechdr->xl_prev = InvalidXLogRecPtr;
-	COMP_CRC32(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev));
+	COMP_CRC32C(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev));
 
 	hdr_rdt.next = rdata;
 	hdr_rdt.data = (char *) rechdr;
@@ -1193,8 +1193,8 @@ begin:;
 		 * Now that xl_prev has been filled in, finish CRC calculation of the
 		 * record header.
 		 */
-		COMP_CRC32(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr));
-		FIN_CRC32(rdata_crc);
+		COMP_CRC32C(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr));
+		FIN_CRC32C(rdata_crc);
 		rechdr->xl_crc = rdata_crc;
 
 		/*
@@ -4344,11 +4344,11 @@ WriteControlFile(void)
 	ControlFile->float8ByVal = FLOAT8PASSBYVAL;
 
 	/* Contents are protected with a CRC */
-	INIT_CRC32(ControlFile->crc);
-	COMP_CRC32(ControlFile->crc,
-			   (char *) ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(ControlFile->crc);
+	INIT_CRC32C(ControlFile->crc);
+	COMP_CRC32C(ControlFile->crc,
+				(char *) ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(ControlFile->crc);
 
 	/*
 	 * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
@@ -4444,13 +4444,13 @@ ReadControlFile(void)
 				 errhint("It looks like you need to initdb.")));
 
 	/* Now check the CRC. */
-	INIT_CRC32(crc);
-	COMP_CRC32(crc,
-			   (char *) ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc,
+				(char *) ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(crc, ControlFile->crc))
+	if (!EQ_CRC32C(crc, ControlFile->crc))
 		ereport(FATAL,
 				(errmsg("incorrect checksum in control file")));
 
@@ -4593,11 +4593,11 @@ UpdateControlFile(void)
 {
 	int			fd;
 
-	INIT_CRC32(ControlFile->crc);
-	COMP_CRC32(ControlFile->crc,
-			   (char *) ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(ControlFile->crc);
+	INIT_CRC32C(ControlFile->crc);
+	COMP_CRC32C(ControlFile->crc,
+				(char *) ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(ControlFile->crc);
 
 	fd = BasicOpenFile(XLOG_CONTROL_FILE,
 					   O_RDWR | PG_BINARY,
@@ -4975,10 +4975,10 @@ BootStrapXLOG(void)
 	record->xl_rmid = RM_XLOG_ID;
 	memcpy(XLogRecGetData(record), &checkPoint, sizeof(checkPoint));
 
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, &checkPoint, sizeof(checkPoint));
-	COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, &checkPoint, sizeof(checkPoint));
+	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	FIN_CRC32C(crc);
 	record->xl_crc = crc;
 
 	/* Create first XLOG segment file */
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index f06daa2..da7ed92 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -684,8 +684,8 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
 		return false;
 	}
 	remaining -= SizeOfXLogRecord + len;
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, XLogRecGetData(record), len);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, XLogRecGetData(record), len);
 
 	/* Add in the backup blocks, if any */
 	blk = (char *) XLogRecGetData(record) + len;
@@ -722,7 +722,7 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
 			return false;
 		}
 		remaining -= blen;
-		COMP_CRC32(crc, blk, blen);
+		COMP_CRC32C(crc, blk, blen);
 		blk += blen;
 	}
 
@@ -736,10 +736,10 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
 	}
 
 	/* Finally include the record header */
-	COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc));
-	FIN_CRC32(crc);
+	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(record->xl_crc, crc))
+	if (!EQ_CRC32C(record->xl_crc, crc))
 	{
 		report_invalid_record(state,
 			   "incorrect resource manager data checksum in record at %X/%X",
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 5e59c6b..71c5fe2 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1517,9 +1517,9 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 	ondisk->magic = SNAPBUILD_MAGIC;
 	ondisk->version = SNAPBUILD_VERSION;
 	ondisk->length = needed_length;
-	INIT_CRC32(ondisk->checksum);
-	COMP_CRC32(ondisk->checksum,
-			   ((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize,
+	INIT_CRC32C(ondisk->checksum);
+	COMP_CRC32C(ondisk->checksum,
+				((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize,
 			SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize);
 	ondisk_c += sizeof(SnapBuildOnDisk);
 
@@ -1531,20 +1531,20 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 	ondisk->builder.running.xip = NULL;
 	ondisk->builder.committed.xip = NULL;
 
-	COMP_CRC32(ondisk->checksum,
-			   &ondisk->builder,
-			   sizeof(SnapBuild));
+	COMP_CRC32C(ondisk->checksum,
+				&ondisk->builder,
+				sizeof(SnapBuild));
 
 	/* copy running xacts */
 	sz = sizeof(TransactionId) * builder->running.xcnt_space;
 	memcpy(ondisk_c, builder->running.xip, sz);
-	COMP_CRC32(ondisk->checksum, ondisk_c, sz);
+	COMP_CRC32C(ondisk->checksum, ondisk_c, sz);
 	ondisk_c += sz;
 
 	/* copy committed xacts */
 	sz = sizeof(TransactionId) * builder->committed.xcnt;
 	memcpy(ondisk_c, builder->committed.xip, sz);
-	COMP_CRC32(ondisk->checksum, ondisk_c, sz);
+	COMP_CRC32C(ondisk->checksum, ondisk_c, sz);
 	ondisk_c += sz;
 
 	/* we have valid data now, open tempfile and write it there */
@@ -1672,8 +1672,8 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				(errmsg("snapbuild state file \"%s\" has unsupported version %u instead of %u",
 						path, ondisk.version, SNAPBUILD_VERSION)));
 
-	INIT_CRC32(checksum);
-	COMP_CRC32(checksum,
+	INIT_CRC32C(checksum);
+	COMP_CRC32C(checksum,
 			   ((char *) &ondisk) + SnapBuildOnDiskNotChecksummedSize,
 			SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize);
 
@@ -1687,7 +1687,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				 errmsg("could not read file \"%s\", read %d of %d: %m",
 						path, readBytes, (int) sizeof(SnapBuild))));
 	}
-	COMP_CRC32(checksum, &ondisk.builder, sizeof(SnapBuild));
+	COMP_CRC32C(checksum, &ondisk.builder, sizeof(SnapBuild));
 
 	/* restore running xacts information */
 	sz = sizeof(TransactionId) * ondisk.builder.running.xcnt_space;
@@ -1701,7 +1701,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				 errmsg("could not read file \"%s\", read %d of %d: %m",
 						path, readBytes, (int) sz)));
 	}
-	COMP_CRC32(checksum, ondisk.builder.running.xip, sz);
+	COMP_CRC32C(checksum, ondisk.builder.running.xip, sz);
 
 	/* restore committed xacts information */
 	sz = sizeof(TransactionId) * ondisk.builder.committed.xcnt;
@@ -1715,12 +1715,12 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				 errmsg("could not read file \"%s\", read %d of %d: %m",
 						path, readBytes, (int) sz)));
 	}
-	COMP_CRC32(checksum, ondisk.builder.committed.xip, sz);
+	COMP_CRC32C(checksum, ondisk.builder.committed.xip, sz);
 
 	CloseTransientFile(fd);
 
 	/* verify checksum of what we've read */
-	if (!EQ_CRC32(checksum, ondisk.checksum))
+	if (!EQ_CRC32C(checksum, ondisk.checksum))
 		ereport(ERROR,
 				(errcode_for_file_access(),
 				 errmsg("snapbuild state file %s: checksum mismatch, is %u, should be %u",
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index f355f13..2c3ea55 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -993,7 +993,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
 	}
 
 	cp.magic = SLOT_MAGIC;
-	INIT_CRC32(cp.checksum);
+	INIT_CRC32C(cp.checksum);
 	cp.version = 1;
 	cp.length = ReplicationSlotOnDiskDynamicSize;
 
@@ -1003,9 +1003,9 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
 
 	SpinLockRelease(&slot->mutex);
 
-	COMP_CRC32(cp.checksum,
-			   (char *) (&cp) + ReplicationSlotOnDiskConstantSize,
-			   ReplicationSlotOnDiskDynamicSize);
+	COMP_CRC32C(cp.checksum,
+				(char *) (&cp) + ReplicationSlotOnDiskConstantSize,
+				ReplicationSlotOnDiskDynamicSize);
 
 	if ((write(fd, &cp, sizeof(cp))) != sizeof(cp))
 	{
@@ -1181,13 +1181,13 @@ RestoreSlotFromDisk(const char *name)
 
 	CloseTransientFile(fd);
 
-	/* now verify the CRC32 */
-	INIT_CRC32(checksum);
-	COMP_CRC32(checksum,
-			   (char *) &cp + ReplicationSlotOnDiskConstantSize,
-			   ReplicationSlotOnDiskDynamicSize);
+	/* now verify the CRC */
+	INIT_CRC32C(checksum);
+	COMP_CRC32C(checksum,
+				(char *) &cp + ReplicationSlotOnDiskConstantSize,
+				ReplicationSlotOnDiskDynamicSize);
 
-	if (!EQ_CRC32(checksum, cp.checksum))
+	if (!EQ_CRC32C(checksum, cp.checksum))
 		ereport(PANIC,
 				(errmsg("replication slot file %s: checksum mismatch, is %u, should be %u",
 						path, checksum, cp.checksum)));
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index 8003918..e9cff4f 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -201,9 +201,9 @@ gtsvector_compress(PG_FUNCTION_ARGS)
 		{
 			pg_crc32	c;
 
-			INIT_CRC32(c);
-			COMP_CRC32(c, words + ptr->pos, ptr->len);
-			FIN_CRC32(c);
+			INIT_LEGACY_CRC32(c);
+			COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len);
+			FIN_LEGACY_CRC32(c);
 
 			*arr = *(int32 *) &c;
 			arr++;
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index c8011a8..5226bae 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -280,9 +280,9 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool
 				 errmsg("word is too long in tsquery: \"%s\"",
 						state->buffer)));
 
-	INIT_CRC32(valcrc);
-	COMP_CRC32(valcrc, strval, lenval);
-	FIN_CRC32(valcrc);
+	INIT_LEGACY_CRC32(valcrc);
+	COMP_LEGACY_CRC32(valcrc, strval, lenval);
+	FIN_LEGACY_CRC32(valcrc);
 	pushValue_internal(state, valcrc, state->curop - state->op, lenval, weight, prefix);
 
 	/* append the value string to state.op, enlarging buffer if needed first */
@@ -883,9 +883,9 @@ tsqueryrecv(PG_FUNCTION_ARGS)
 
 			/* Looks valid. */
 
-			INIT_CRC32(valcrc);
-			COMP_CRC32(valcrc, val, val_len);
-			FIN_CRC32(valcrc);
+			INIT_LEGACY_CRC32(valcrc);
+			COMP_LEGACY_CRC32(valcrc, val, val_len);
+			FIN_LEGACY_CRC32(valcrc);
 
 			item->qoperand.weight = weight;
 			item->qoperand.prefix = (prefix) ? true : false;
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 95a2689..b6b1330 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -84,7 +84,7 @@ typedef struct RelMapFile
 	int32		magic;			/* always RELMAPPER_FILEMAGIC */
 	int32		num_mappings;	/* number of valid RelMapping entries */
 	RelMapping	mappings[MAX_MAPPINGS];
-	int32		crc;			/* CRC of all above */
+	pg_crc32	crc;			/* CRC of all above */
 	int32		pad;			/* to make the struct size be 512 exactly */
 } RelMapFile;
 
@@ -673,11 +673,11 @@ load_relmap_file(bool shared)
 						mapfilename)));
 
 	/* verify the CRC */
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, (char *) map, offsetof(RelMapFile, crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(crc, map->crc))
+	if (!EQ_CRC32C(crc, map->crc))
 		ereport(FATAL,
 		  (errmsg("relation mapping file \"%s\" contains incorrect checksum",
 				  mapfilename)));
@@ -719,9 +719,9 @@ write_relmap_file(bool shared, RelMapFile *newmap,
 	if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS)
 		elog(ERROR, "attempt to write bogus relation mapping");
 
-	INIT_CRC32(newmap->crc);
-	COMP_CRC32(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
-	FIN_CRC32(newmap->crc);
+	INIT_CRC32C(newmap->crc);
+	COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
+	FIN_CRC32C(newmap->crc);
 
 	/*
 	 * Open the target file.  We prefer to do this before entering the
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 32cc100..b2e0793 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -178,13 +178,13 @@ main(int argc, char *argv[])
 	close(fd);
 
 	/* Check the CRC. */
-	INIT_CRC32(crc);
-	COMP_CRC32(crc,
-			   (char *) &ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc,
+				(char *) &ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(crc, ControlFile.crc))
+	if (!EQ_CRC32C(crc, ControlFile.crc))
 		printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
 				 "Either the file is corrupt, or it has a different layout than this program\n"
 				 "is expecting.  The results below are untrustworthy.\n\n"));
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index f4c1eaf..e224e67 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -456,13 +456,13 @@ ReadControlFile(void)
 	  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
 	{
 		/* Check the CRC. */
-		INIT_CRC32(crc);
-		COMP_CRC32(crc,
-				   buffer,
-				   offsetof(ControlFileData, crc));
-		FIN_CRC32(crc);
+		INIT_CRC32C(crc);
+		COMP_CRC32C(crc,
+					buffer,
+					offsetof(ControlFileData, crc));
+		FIN_CRC32C(crc);
 
-		if (EQ_CRC32(crc, ((ControlFileData *) buffer)->crc))
+		if (EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
 		{
 			/* Valid data... */
 			memcpy(&ControlFile, buffer, sizeof(ControlFile));
@@ -747,11 +747,11 @@ RewriteControlFile(void)
 	ControlFile.xlog_seg_size = XLogSegSize;
 
 	/* Contents are protected with a CRC */
-	INIT_CRC32(ControlFile.crc);
-	COMP_CRC32(ControlFile.crc,
-			   (char *) &ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(ControlFile.crc);
+	INIT_CRC32C(ControlFile.crc);
+	COMP_CRC32C(ControlFile.crc,
+				(char *) &ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(ControlFile.crc);
 
 	/*
 	 * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
@@ -1032,10 +1032,10 @@ WriteEmptyXLOG(void)
 	memcpy(XLogRecGetData(record), &ControlFile.checkPointCopy,
 		   sizeof(CheckPoint));
 
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint));
-	COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint));
+	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	FIN_CRC32C(crc);
 	record->xl_crc = crc;
 
 	/* Write the first page */
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index f43f4aa..978b06a 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -7,9 +7,22 @@
  * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
  * http://www.ross.net/crc/ or several other net sites.
  *
- * We use a normal (not "reflected", in Williams' terms) CRC, using initial
- * all-ones register contents and a final bit inversion.
+ * We have three slightly different variants of a 32-bit CRC calculation:
+ * CRC-32C (Castagnoli polynomial), CRC-32 (Ethernet polynomial), and a legacy
+ * CRC-32 version that uses the lookup table in a funny way. They all consist
+ * of four macros:
  *
+ * INIT_<variant>(crc)
+ *		Initialize a CRC accumulator
+ *
+ * COMP_<variant>(crc, data, len)
+ *		Accumulate some (more) bytes into a CRC
+ *
+ * FIN_<variant>(crc)
+ *		Finish a CRC calculation
+ *
+ * EQ_<variant>(c1, c2)
+ *		Check for equality of two CRCs.
  *
  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -28,29 +41,80 @@
 
 typedef uint32 pg_crc32;
 
-/* Initialize a CRC accumulator */
-#define INIT_CRC32(crc) ((crc) = 0xFFFFFFFF)
+/*
+ * CRC calculation using the CRC-32C (Castagnoli) polynomial. We use all-ones
+ * as the initial register contents and final bit inversion. This is the same
+ * algorithm used e.g. in iSCSI. See RFC 3385 for more details on the choice
+ * of polynomial.
+ */
+#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
+#define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
+#define COMP_CRC32C(crc, data, len)	\
+	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+#define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
-/* Finish a CRC calculation */
-#define FIN_CRC32(crc)	((crc) ^= 0xFFFFFFFF)
+/*
+ * CRC-32, the same used e.g. in Ethernet.
+ *
+ * This is currently only used in ltree and hstore contrib modules. It uses
+ * the same lookup table as the legacy algorithm below. New code should
+ * use the Castagnoli version instead.
+ */
+#define INIT_TRADITIONAL_CRC32(crc) ((crc) = 0xFFFFFFFF)
+#define FIN_TRADITIONAL_CRC32(crc)	((crc) ^= 0xFFFFFFFF)
+#define COMP_TRADITIONAL_CRC32(crc, data, len)	\
+	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32_table)
+#define EQ_TRADITIONAL_CRC32(c1, c2) ((c1) == (c2))
+
+/*
+ * The CRC algorithm used for WAL et al in pre-9.5 versions.
+ *
+ * This closely resembles the normal CRC-32 algorithm, but is subtly
+ * different. Using Williams' terms, we use the "normal" table, but with
+ * "reflected" code. That's bogus, but it was like that for years before
+ * anyone noticed. It does not correspond to any polynomial in a normal CRC
+ * algorithm, so it's not clear what the error-detection properties of this
+ * algorithm actually are.
+ *
+ * We still need to carry this around because this is used in a few on-disk
+ * structures that need to be pg_upgradeable. It should not be used in new
+ * code.
+ */
+#define INIT_LEGACY_CRC32(crc) ((crc) = 0xFFFFFFFF)
+#define FIN_LEGACY_CRC32(crc)	((crc) ^= 0xFFFFFFFF)
+#define COMP_LEGACY_CRC32(crc, data, len)	\
+	COMP_CRC32_REFLECTED_TABLE(crc, data, len, pg_crc32_table)
+#define EQ_LEGACY_CRC32(c1, c2) ((c1) == (c2))
 
-/* Accumulate some (more) bytes into a CRC */
-#define COMP_CRC32(crc, data, len)	\
-do { \
+/*
+ * Common code for CRC computation using a lookup table.
+ */
+#define COMP_CRC32_NORMAL_TABLE(crc, data, len, table)			  \
+do {															  \
 	const unsigned char *__data = (const unsigned char *) (data); \
 	uint32		__len = (len); \
 \
 	while (__len-- > 0) \
 	{ \
-		int		__tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \
-		(crc) = pg_crc32_table[__tab_index] ^ ((crc) << 8); \
+		int		__tab_index = ((int) (crc) ^ *__data++) & 0xFF; \
+		(crc) = table[__tab_index] ^ ((crc) >> 8); \
 	} \
 } while (0)
 
-/* Check for equality of two CRCs */
-#define EQ_CRC32(c1,c2)  ((c1) == (c2))
+#define COMP_CRC32_REFLECTED_TABLE(crc, data, len, table) \
+do {															  \
+	const unsigned char *__data = (const unsigned char *) (data); \
+	uint32		__len = (len); \
+\
+	while (__len-- > 0) \
+	{ \
+		int		__tab_index = ((int) (crc) ^ *__data++) & 0xFF; \
+		(crc) = table[__tab_index] ^ ((crc) >> 8); \
+	} \
+} while (0)
 
-/* Constant table for CRC calculation */
+/* Constant tables for CRC-32C and CRC-32 polynomials */
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index f566137..e070ec1 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -25,6 +25,79 @@
 #ifndef PG_CRC_TABLES_H
 #define PG_CRC_TABLES_H
 
+
+/*
+ * This table is based on the so-called Castagnoli polynomial (the same
+ * that is used e.g. in iSCSI).
+ */
+const uint32 pg_crc32c_table[256] = {
+	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+};
+
+
 /*
  * This table is based on the polynomial
  *	x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-- 
2.1.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to