2121 * as the collations of Vars and, most notably, the values of constants.
2222 *
2323 * This jumble is acquired at the end of parse analysis of each query, and
24- * a 32 -bit hash of it is stored into the query's Query.queryId field.
24+ * a 64 -bit hash of it is stored into the query's Query.queryId field.
2525 * The server then copies this value around, making it available in plan
2626 * tree(s) generated from the query. The executor can then use this value
2727 * to blame query costs on the proper queryId.
@@ -95,7 +95,7 @@ PG_MODULE_MAGIC;
9595#define PGSS_TEXT_FILE PG_STAT_TMP_DIR "/pgss_query_texts.stat"
9696
9797/* Magic number identifying the stats file format */
98- static const uint32 PGSS_FILE_HEADER = 0x20140125 ;
98+ static const uint32 PGSS_FILE_HEADER = 0x20171004 ;
9999
100100/* PostgreSQL major version number, changes in which invalidate all entries */
101101static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100 ;
@@ -130,7 +130,7 @@ typedef struct pgssHashKey
130130{
131131 Oid userid ; /* user OID */
132132 Oid dbid ; /* database OID */
133- uint32 queryid ; /* query identifier */
133+ uint64 queryid ; /* query identifier */
134134} pgssHashKey ;
135135
136136/*
@@ -301,10 +301,8 @@ static void pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
301301 ProcessUtilityContext context , ParamListInfo params ,
302302 QueryEnvironment * queryEnv ,
303303 DestReceiver * dest , char * completionTag );
304- static uint32 pgss_hash_fn (const void * key , Size keysize );
305- static int pgss_match_fn (const void * key1 , const void * key2 , Size keysize );
306- static uint32 pgss_hash_string (const char * str , int len );
307- static void pgss_store (const char * query , uint32 queryId ,
304+ static uint64 pgss_hash_string (const char * str , int len );
305+ static void pgss_store (const char * query , uint64 queryId ,
308306 int query_location , int query_len ,
309307 double total_time , uint64 rows ,
310308 const BufferUsage * bufusage ,
@@ -500,12 +498,10 @@ pgss_shmem_startup(void)
500498 memset (& info , 0 , sizeof (info ));
501499 info .keysize = sizeof (pgssHashKey );
502500 info .entrysize = sizeof (pgssEntry );
503- info .hash = pgss_hash_fn ;
504- info .match = pgss_match_fn ;
505501 pgss_hash = ShmemInitHash ("pg_stat_statements hash" ,
506502 pgss_max , pgss_max ,
507503 & info ,
508- HASH_ELEM | HASH_FUNCTION | HASH_COMPARE );
504+ HASH_ELEM | HASH_BLOBS );
509505
510506 LWLockRelease (AddinShmemInitLock );
511507
@@ -781,7 +777,7 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query)
781777 prev_post_parse_analyze_hook (pstate , query );
782778
783779 /* Assert we didn't do this already */
784- Assert (query -> queryId == 0 );
780+ Assert (query -> queryId == UINT64CONST ( 0 ) );
785781
786782 /* Safety check... */
787783 if (!pgss || !pgss_hash )
@@ -797,7 +793,7 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query)
797793 */
798794 if (query -> utilityStmt )
799795 {
800- query -> queryId = 0 ;
796+ query -> queryId = UINT64CONST ( 0 ) ;
801797 return ;
802798 }
803799
@@ -812,14 +808,15 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query)
812808
813809 /* Compute query ID and mark the Query node with it */
814810 JumbleQuery (& jstate , query );
815- query -> queryId = hash_any (jstate .jumble , jstate .jumble_len );
811+ query -> queryId =
812+ DatumGetUInt64 (hash_any_extended (jstate .jumble , jstate .jumble_len , 0 ));
816813
817814 /*
818815 * If we are unlucky enough to get a hash of zero, use 1 instead, to
819816 * prevent confusion with the utility-statement case.
820817 */
821- if (query -> queryId == 0 )
822- query -> queryId = 1 ;
818+ if (query -> queryId == UINT64CONST ( 0 ) )
819+ query -> queryId = UINT64CONST ( 1 ) ;
823820
824821 /*
825822 * If we were able to identify any ignorable constants, we immediately
@@ -855,7 +852,7 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
855852 * counting of optimizable statements that are directly contained in
856853 * utility statements.
857854 */
858- if (pgss_enabled () && queryDesc -> plannedstmt -> queryId != 0 )
855+ if (pgss_enabled () && queryDesc -> plannedstmt -> queryId != UINT64CONST ( 0 ) )
859856 {
860857 /*
861858 * Set up to track total elapsed time in ExecutorRun. Make sure the
@@ -926,9 +923,9 @@ pgss_ExecutorFinish(QueryDesc *queryDesc)
926923static void
927924pgss_ExecutorEnd (QueryDesc * queryDesc )
928925{
929- uint32 queryId = queryDesc -> plannedstmt -> queryId ;
926+ uint64 queryId = queryDesc -> plannedstmt -> queryId ;
930927
931- if (queryId != 0 && queryDesc -> totaltime && pgss_enabled ())
928+ if (queryId != UINT64CONST ( 0 ) && queryDesc -> totaltime && pgss_enabled ())
932929 {
933930 /*
934931 * Make sure stats accumulation is done. (Note: it's okay if several
@@ -1069,45 +1066,16 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
10691066 }
10701067}
10711068
1072- /*
1073- * Calculate hash value for a key
1074- */
1075- static uint32
1076- pgss_hash_fn (const void * key , Size keysize )
1077- {
1078- const pgssHashKey * k = (const pgssHashKey * ) key ;
1079-
1080- return hash_uint32 ((uint32 ) k -> userid ) ^
1081- hash_uint32 ((uint32 ) k -> dbid ) ^
1082- hash_uint32 ((uint32 ) k -> queryid );
1083- }
1084-
1085- /*
1086- * Compare two keys - zero means match
1087- */
1088- static int
1089- pgss_match_fn (const void * key1 , const void * key2 , Size keysize )
1090- {
1091- const pgssHashKey * k1 = (const pgssHashKey * ) key1 ;
1092- const pgssHashKey * k2 = (const pgssHashKey * ) key2 ;
1093-
1094- if (k1 -> userid == k2 -> userid &&
1095- k1 -> dbid == k2 -> dbid &&
1096- k1 -> queryid == k2 -> queryid )
1097- return 0 ;
1098- else
1099- return 1 ;
1100- }
1101-
11021069/*
11031070 * Given an arbitrarily long query string, produce a hash for the purposes of
11041071 * identifying the query, without normalizing constants. Used when hashing
11051072 * utility statements.
11061073 */
1107- static uint32
1074+ static uint64
11081075pgss_hash_string (const char * str , int len )
11091076{
1110- return hash_any ((const unsigned char * ) str , len );
1077+ return DatumGetUInt64 (hash_any_extended ((const unsigned char * ) str ,
1078+ len , 0 ));
11111079}
11121080
11131081/*
@@ -1121,7 +1089,7 @@ pgss_hash_string(const char *str, int len)
11211089 * query string. total_time, rows, bufusage are ignored in this case.
11221090 */
11231091static void
1124- pgss_store (const char * query , uint32 queryId ,
1092+ pgss_store (const char * query , uint64 queryId ,
11251093 int query_location , int query_len ,
11261094 double total_time , uint64 rows ,
11271095 const BufferUsage * bufusage ,
@@ -1173,7 +1141,7 @@ pgss_store(const char *query, uint32 queryId,
11731141 /*
11741142 * For utility statements, we just hash the query string to get an ID.
11751143 */
1176- if (queryId == 0 )
1144+ if (queryId == UINT64CONST ( 0 ) )
11771145 queryId = pgss_hash_string (query , query_len );
11781146
11791147 /* Set up key for hashtable search */
@@ -2324,8 +2292,10 @@ AppendJumble(pgssJumbleState *jstate, const unsigned char *item, Size size)
23242292
23252293 if (jumble_len >= JUMBLE_SIZE )
23262294 {
2327- uint32 start_hash = hash_any ( jumble , JUMBLE_SIZE ) ;
2295+ uint64 start_hash ;
23282296
2297+ start_hash = DatumGetUInt64 (hash_any_extended (jumble ,
2298+ JUMBLE_SIZE , 0 ));
23292299 memcpy (jumble , & start_hash , sizeof (start_hash ));
23302300 jumble_len = sizeof (start_hash );
23312301 }
0 commit comments