Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

...
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 2 contributors
Commits on Apr 10, 2012
Heikki Linnakangas hlinnaka Fix the logic for the first data key on non-leaf b-tree index tuples.…
… Per

the comments and README, they are not real tuples, but the the check to
detect them was not accounting high-keys correctly.

Also, be consistent about printing the offset number as a 1-based number in
debug/warning messages.
ebf4742
Commits on Apr 15, 2012
Tomas Vondra Merge branch 'master' of git://github.com/hlinnaka/pg_check a0fb849
Showing with 36 additions and 29 deletions.
  1. +34 −27 src/index.c
  2. +2 −2 src/index.h
61 src/index.c
View
@@ -140,13 +140,13 @@ uint32 check_index_tuple(Relation rel, PageHeader header, int block, int i, char
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)));
+ 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)));
+ ereport(DEBUG3,(errmsg("[%d:%d] skipped (not LP_NORMAL)", block, (j+1))));
continue;
}
@@ -163,7 +163,7 @@ uint32 check_index_tuple(Relation rel, PageHeader header, int block, int i, char
/* 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);
+ nerrs += check_index_tuple_attributes(rel, header, block, i + 1, buffer);
}
return nerrs;
@@ -171,7 +171,7 @@ uint32 check_index_tuple(Relation rel, PageHeader header, int block, int i, char
}
/* checks the individual attributes of the tuple */
-uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block, int i, char *buffer) {
+uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block, OffsetNumber offnum, char *buffer) {
IndexTuple tuple;
uint32 nerrs = 0;
@@ -179,20 +179,22 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
bits8 * bitmap;
BTPageOpaque opaque;
-
- ereport(DEBUG2,(errmsg("[%d:%d] checking attributes for the tuple", block, i)));
+ ItemId linp;
+
+ ereport(DEBUG2,(errmsg("[%d:%d] checking attributes for the tuple", block, offnum)));
/* get the index tuple and info about the page */
- tuple = (IndexTuple)(buffer + header->pd_linp[i].lp_off);
+ linp = &header->pd_linp[offnum - 1];
+ tuple = (IndexTuple)(buffer + linp->lp_off);
opaque = (BTPageOpaque)(buffer + header->pd_special);
/* current attribute offset - always starts at (buffer + off) */
- off = header->pd_linp[i].lp_off + IndexInfoFindDataOffset(tuple->t_info);
+ off = linp->lp_off + IndexInfoFindDataOffset(tuple->t_info);
- ereport(DEBUG3,(errmsg("[%d:%d] tuple has %d attributes", block, (i+1),
+ ereport(DEBUG3,(errmsg("[%d:%d] tuple has %d attributes", block, offnum,
RelationGetNumberOfAttributes(rel))));
-
- bitmap = (bits8*)(buffer + header->pd_linp[i].lp_off + sizeof(IndexTupleData));
+ /* XXX: MAXALIGN */
+ bitmap = (bits8*)(buffer + linp->lp_off + sizeof(IndexTupleData));
/* TODO This is mostly copy'n'paste from check_heap_tuple_attributes,
so maybe it could be refactored to share the code. */
@@ -204,12 +206,12 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
Use P_LEFTMOST/P_ISLEAF to identify such cases (for the leftmost item only)
and set len = 0.
*/
-
- if (P_LEFTMOST(opaque) && (! P_ISLEAF(opaque)) && (i == 0)) {
- ereport(DEBUG3, (errmsg("[%d:%d] leftmost tuple on non-leaf block => no data, skipping", block, i)));
+
+ if (P_LEFTMOST(opaque) && !P_ISLEAF(opaque) && offnum == P_FIRSTDATAKEY(opaque)) {
+ ereport(DEBUG3, (errmsg("[%d:%d] leftmost tuple on non-leaf block => no data, skipping", block, offnum)));
return nerrs;
}
-
+
/* check all the index attributes */
for (j = 0; j < rel->rd_att->natts; j++) {
@@ -222,7 +224,7 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
/* if the attribute is marked as NULL (in the tuple header), skip to the next attribute */
if (IndexTupleHasNulls(tuple) && att_isnull(j, bitmap)) {
- ereport(DEBUG3, (errmsg("[%d:%d] attribute '%s' is NULL (skipping)", block, (i+1), rel->rd_att->attrs[j]->attname.data)));
+ ereport(DEBUG3, (errmsg("[%d:%d] attribute '%s' is NULL (skipping)", block, offnum, rel->rd_att->attrs[j]->attname.data)));
continue;
}
@@ -243,7 +245,7 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
len = VARSIZE_ANY(buffer + off);
if (len < 0) {
- ereport(WARNING, (errmsg("[%d:%d] attribute '%s' has negative length < 0 (%d)", block, (i+1), rel->rd_att->attrs[j]->attname.data, len)));
+ ereport(WARNING, (errmsg("[%d:%d] attribute '%s' has negative length < 0 (%d)", block, offnum, rel->rd_att->attrs[j]->attname.data, len)));
++nerrs;
break;
}
@@ -251,7 +253,7 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
if (VARATT_IS_COMPRESSED(buffer + off)) {
/* the raw length should be less than 1G (and positive) */
if ((VARRAWSIZE_4B_C(buffer + off) < 0) || (VARRAWSIZE_4B_C(buffer + off) > 1024*1024)) {
- ereport(WARNING, (errmsg("[%d:%d] attribute '%s' has invalid length %d (should be between 0 and 1G)", block, (i+1), rel->rd_att->attrs[j]->attname.data, VARRAWSIZE_4B_C(buffer + off))));
+ ereport(WARNING, (errmsg("[%d:%d] attribute '%s' has invalid length %d (should be between 0 and 1G)", block, offnum, rel->rd_att->attrs[j]->attname.data, VARRAWSIZE_4B_C(buffer + off))));
++nerrs;
/* no break here, this does not break the page structure - we may check the other attributes */
}
@@ -263,7 +265,7 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
/* get the C-string length (at most to the end of tuple), +1 as it does not include '\0' at the end */
/* if the string is not properly terminated, then this returns 'remaining space + 1' so it's detected */
- len = strnlen(buffer + off, header->pd_linp[i].lp_off + len + header->pd_linp[i].lp_len - off) + 1;
+ len = strnlen(buffer + off, linp->lp_off + len + linp->lp_len - off) + 1;
}
@@ -271,8 +273,11 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
* the tuple end, stop validating the other rows (we don't know where to
* continue anyway). */
- if (off + len > (header->pd_linp[i].lp_off + header->pd_linp[i].lp_len)) {
- ereport(WARNING, (errmsg("[%d:%d] attribute '%s' (off=%d len=%d) overflows tuple end (off=%d, len=%d)", block, (i+1), rel->rd_att->attrs[j]->attname.data, off, len, header->pd_linp[i].lp_off, header->pd_linp[i].lp_len)));
+ if (off + len > (linp->lp_off + linp->lp_len)) {
+ ereport(WARNING,
+ (errmsg("[%d:%d] attribute '%s' (off=%d len=%d) overflows tuple end (off=%d, len=%d)",
+ block, offnum, rel->rd_att->attrs[j]->attname.data,
+ off, len, linp->lp_off, linp->lp_len)));
++nerrs;
break;
}
@@ -280,18 +285,20 @@ uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block,
/* skip to the next attribute */
off += len;
- ereport(DEBUG3,(errmsg("[%d:%d] attribute '%s' len=%d", block, (i+1), rel->rd_att->attrs[j]->attname.data, len)));
-
+ ereport(DEBUG3,(errmsg("[%d:%d] attribute '%s' len=%d", block, offnum, rel->rd_att->attrs[j]->attname.data, len)));
}
- ereport(DEBUG3,(errmsg("[%d:%d] last attribute ends at %d, tuple ends at %d", block, (i+1), off, header->pd_linp[i].lp_off + header->pd_linp[i].lp_len)));
+ ereport(DEBUG3,
+ (errmsg("[%d:%d] last attribute ends at %d, tuple ends at %d",
+ block, offnum, off, linp->lp_off + linp->lp_len)));
/* after the last attribute, the offset should be exactly the same as the end of the tuple */
- if (MAXALIGN(off) != header->pd_linp[i].lp_off + header->pd_linp[i].lp_len) {
- ereport(WARNING, (errmsg("[%d:%d] the last attribute ends at %d but the tuple ends at %d", block, (i+1), off, header->pd_linp[i].lp_off + header->pd_linp[i].lp_len)));
+ if (MAXALIGN(off) != linp->lp_off + linp->lp_len) {
+ ereport(WARNING,
+ (errmsg("[%d:%d] the last attribute ends at %d but the tuple ends at %d",
+ block, offnum, off, linp->lp_off + linp->lp_len)));
++nerrs;
}
return nerrs;
-
}
4 src/index.h
View
@@ -9,6 +9,6 @@
uint32 check_index_page(Relation rel, PageHeader header, char *buffer, int block);
uint32 check_index_tuples(Relation rel, PageHeader header, char *buffer, int block);
uint32 check_index_tuple(Relation rel, PageHeader header, int block, int i, char *buffer);
-uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block, int i, char *buffer);
+uint32 check_index_tuple_attributes(Relation rel, PageHeader header, int block, OffsetNumber offnum, char *buffer);
-#endif
+#endif

No commit comments for this range

Something went wrong with that request. Please try again.