| 2931 | } |
| 2932 | |
| 2933 | void Validation::checkDPinPP(jrd_rel* relation, ULONG page_number) |
| 2934 | { |
| 2935 | /************************************** |
| 2936 | * |
| 2937 | * Functional description |
| 2938 | * Check if data page presented in pointer page. |
| 2939 | * If not we try to fix it by setting pointer page slot in the page_number. |
| 2940 | * Early in walk_chain we observed that this page in related to the relation so we skip such kind of check here. |
| 2941 | **************************************/ |
| 2942 | |
| 2943 | WIN window(DB_PAGE_SPACE, page_number); |
| 2944 | data_page* dpage; |
| 2945 | fetch_page(false, page_number, pag_data, &window, &dpage); |
| 2946 | const ULONG sequence = dpage->dpg_sequence; |
| 2947 | const bool dpEmpty = (dpage->dpg_count == 0); |
| 2948 | release_page(&window); |
| 2949 | |
| 2950 | USHORT slot; |
| 2951 | ULONG pp_sequence; |
| 2952 | Database* dbb = vdr_tdbb->getDatabase(); |
| 2953 | DECOMPOSE(sequence, dbb->dbb_dp_per_pp, pp_sequence, slot); |
| 2954 | |
| 2955 | const vcl* vector = relation->getBasePages()->rel_pages; |
| 2956 | pointer_page* ppage = 0; |
| 2957 | if (pp_sequence < vector->count()) |
| 2958 | { |
| 2959 | fetch_page(false, (*vector)[pp_sequence], pag_pointer, &window, &ppage); |
| 2960 | if (slot >= ppage->ppg_count) |
| 2961 | { |
| 2962 | corrupt(VAL_DATA_PAGE_SLOT_NOT_FOUND, relation, page_number, window.win_page.getPageNum(), slot); |
| 2963 | if ((vdr_flags & VDR_update) && slot < dbb->dbb_dp_per_pp) |
| 2964 | { |
| 2965 | CCH_MARK(vdr_tdbb, &window); |
| 2966 | for (USHORT i = ppage->ppg_count; i < slot; i++) |
| 2967 | { |
| 2968 | ppage->ppg_page[i] = 0; |
| 2969 | |
| 2970 | // Clear control fields |
| 2971 | UCHAR* byte = &PPG_DP_BITS_BYTE((UCHAR*) &ppage->ppg_page[dbb->dbb_dp_per_pp], slot); |
| 2972 | *byte = 0; |
| 2973 | } |
| 2974 | ppage->ppg_page[slot] = page_number; |
| 2975 | ppage->ppg_count = slot + 1; |
| 2976 | |
| 2977 | // Restore control fields |
| 2978 | UCHAR* byte = &PPG_DP_BITS_BYTE((UCHAR*) &ppage->ppg_page[dbb->dbb_dp_per_pp], slot); |
| 2979 | restoreFlags(byte, dpage->dpg_header.pag_flags, dpEmpty); |
| 2980 | vdr_fixed++; |
| 2981 | } |
| 2982 | } |
| 2983 | else if (page_number != ppage->ppg_page[slot]) |
| 2984 | { |
| 2985 | corrupt(VAL_DATA_PAGE_SLOT_BAD_VAL, relation, page_number, window.win_page.getPageNum(), slot, ppage->ppg_page[slot]); |
| 2986 | if ((vdr_flags & VDR_update) && !ppage->ppg_page[slot]) |
| 2987 | { |
| 2988 | CCH_MARK(vdr_tdbb, &window); |
| 2989 | ppage->ppg_page[slot] = page_number; |
| 2990 |
nothing calls this directly
no test coverage detected