コード例 #1
0
ファイル: index.c プロジェクト: ecalvo-palominodb/pg_check
/* FIXME This should do exactly the same checks of lp_flags as in heap.c */
uint32 check_index_tuple(Relation rel, PageHeader header, int block, int i, char *buffer) {
  
	uint32 nerrs = 0;
	int j, a, b, c, d;
	
	IndexTuple itup = (IndexTuple)(buffer + header->pd_linp[i].lp_off);
	
	/* FIXME This is used when checking overflowing attributes, but it's not clear what
	 * exactly this means / how it works. Needs a bit more investigation and maybe a review
	 * from soneone who really knows the b-tree implementation. */
	int dlen = IndexTupleSize(itup) - IndexInfoFindDataOffset(itup->t_info);
	
	ereport(DEBUG2,(errmsg("[%d:%d] off=%d len=%d tid=(%d,%d)", block, (i+1),
						   header->pd_linp[i].lp_off, header->pd_linp[i].lp_len,
						   BlockIdGetBlockNumber(&(itup->t_tid.ip_blkid)),
						   itup->t_tid.ip_posid )));
	
	/* check intersection with other tuples */
		  
	/* [A,B] vs [C,D] */
	a = header->pd_linp[i].lp_off;
	b = header->pd_linp[i].lp_off + header->pd_linp[i].lp_len;
	
	ereport(DEBUG2,(errmsg("[%d:%d] checking intersection with other tuples", block, (i+1))));
	
	for (j = 0; j < i; j++) {
	  
		/* FIXME Skip UNUSED/REDIRECT/DEAD tuples */
		if (! (header->pd_linp[i].lp_flags == LP_NORMAL)) {
			ereport(DEBUG3,(errmsg("[%d:%d] skipped (not LP_NORMAL)", block, (j+1))));
			continue;
		}
	  
		c = header->pd_linp[j].lp_off;
		d = header->pd_linp[j].lp_off + header->pd_linp[j].lp_len;

		/* [A,C,B] or [A,D,B] or [C,A,D] or [C,B,D] */
		if (((a < c) && (c < b)) || ((a < d) && (d < b)) ||
			((c < a) && (a < d)) || ((c < b) && (b < d))) {
			ereport(WARNING,(errmsg("[%d:%d] intersects with [%d:%d] (%d,%d) vs. (%d,%d)", block, (i+1), block, j, a, b, c, d)));
			++nerrs;
		}
	}
	
	/* check attributes only for tuples with (lp_flags==LP_NORMAL) */
	if (header->pd_linp[i].lp_flags == LP_NORMAL) {
		nerrs += check_index_tuple_attributes(rel, header, block, i + 1, buffer, dlen);
	}
	
	return nerrs;
	
}
コード例 #2
0
ファイル: index.c プロジェクト: fdr/pg_check
/* FIXME This should do exactly the same checks of lp_flags as in heap.c */
uint32 check_index_tuple(Relation rel, PageHeader header, int block, int i, char *buffer) {
  
	uint32 nerrs = 0;
	int j, a, b, c, d;
	
	IndexTuple itup = (IndexTuple)(buffer + header->pd_linp[i].lp_off);
	
	ereport(DEBUG2,(errmsg("[%d:%d] off=%d len=%d tid=(%d,%d)", block, (i+1),
						   header->pd_linp[i].lp_off, header->pd_linp[i].lp_len,
						   BlockIdGetBlockNumber(&(itup->t_tid.ip_blkid)),
						   itup->t_tid.ip_posid )));
	
	/* check intersection with other tuples */
		  
	/* [A,B] vs [C,D] */
	a = header->pd_linp[i].lp_off;
	b = header->pd_linp[i].lp_off + header->pd_linp[i].lp_len;
	
	ereport(DEBUG2,(errmsg("[%d:%d] checking intersection with other tuples", block, i)));
	
	for (j = 0; j < i; j++) {
	  
		/* FIXME Skip UNUSED/REDIRECT/DEAD tuples */
		if (! (header->pd_linp[i].lp_flags == LP_NORMAL)) {
			ereport(DEBUG3,(errmsg("[%d:%d] skipped (not LP_NORMAL)", block, j)));
			continue;
		}
	  
		c = header->pd_linp[j].lp_off;
		d = header->pd_linp[j].lp_off + header->pd_linp[j].lp_len;

		/* [A,C,B] or [A,D,B] or [C,A,D] or [C,B,D] */
		if (((a < c) && (c < b)) || ((a < d) && (d < b)) ||
			((c < a) && (a < d)) || ((c < b) && (b < d))) {
			ereport(WARNING,(errmsg("[%d:%d] intersects with [%d:%d] (%d,%d) vs. (%d,%d)", block, (i+1), block, j, a, b, c, d)));
			++nerrs;
		}
	}
	
	/* check attributes only for tuples with (lp_flags==LP_NORMAL) */
	if (header->pd_linp[i].lp_flags == LP_NORMAL) {
		nerrs += check_index_tuple_attributes(rel, header, block, i, buffer);
	}
	
	return nerrs;
	
}