mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-18 09:50:07 +08:00
Merge of HACKING from jahlborn
This commit is contained in:
79
HACKING
79
HACKING
@@ -242,6 +242,11 @@ Number of characters in a Memo field: 65,535 when entering data through the
|
||||
user interface; 2 gigabytes of character storage when entering data
|
||||
programmatically. That would mean 31 bits for length.
|
||||
|
||||
Note: if a memo field is marked for compression, only at value which is at
|
||||
most 1024 characters when uncompressed can be compressed. fields longer than
|
||||
that _must_ be stored uncompressed.
|
||||
|
||||
|
||||
LVAL (Long Value) Pages
|
||||
-----------------------
|
||||
|
||||
@@ -306,7 +311,7 @@ next_pg field.
|
||||
| ???? | 2 bytes | max_cols | Max columns a row will have (deletions) |
|
||||
| ???? | 2 bytes | num_var_cols| Number of variable columns in table |
|
||||
| ???? | 2 bytes | num_cols | Number of columns in table (repeat) |
|
||||
| ???? | 4 bytes | num_idx | Number of indexes in table |
|
||||
| ???? | 4 bytes | num_idx | Number of logical indexes in table |
|
||||
| ???? | 4 bytes | num_real_idx| Number of index entries |
|
||||
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||
| | | | usage bitmask for this table. |
|
||||
@@ -337,14 +342,14 @@ next_pg field.
|
||||
| ???? | 1 byte | col_name_len| len of the name of the column |
|
||||
| ???? | n bytes | col_name | Name of the column |
|
||||
+-------------------------------------------------------------------------+
|
||||
| Iterate for indexes with index_type 0 or 1 (30+9 = 39 bytes) |
|
||||
| Iterate for the number of num_real_idx (30+9 = 39 bytes) |
|
||||
+-------------------------------------------------------------------------+
|
||||
| Iterate 10 times for 10 possible columns (10*3 = 30 bytes) |
|
||||
+-------------------------------------------------------------------------+
|
||||
| ???? | 2 bytes | col_num | number of a column (0xFFFF= none) |
|
||||
| ???? | 1 byte | col_order | 0x01 = ascendency order |
|
||||
+-------------------------------------------------------------------------+
|
||||
| ???? | 4 bytes | unknown | |
|
||||
| ???? | 4 bytes | used_pages | Points to usage bitmap for index |
|
||||
| ???? | 4 bytes | first_dp | Data pointer of the index page |
|
||||
| ???? | 1 byte | flags | See flags table for indexes |
|
||||
+-------------------------------------------------------------------------+
|
||||
@@ -353,11 +358,14 @@ next_pg field.
|
||||
| ???? | 4 bytes | index_num | Number of the index |
|
||||
| | | |(warn: not always in the sequential order)|
|
||||
| ???? | 4 bytes | index_num2 | Index into index cols list |
|
||||
| 0x00 | 1 byte | ??? | |
|
||||
| 0xFF | 4 bytes | ??? | |
|
||||
| 0x00 | 4 bytes | ??? | |
|
||||
| 0x04 | 2 bytes | ??? | |
|
||||
| ???? | 1 byte | primary_key | 0x01 if this index is primary |
|
||||
| 0x00 | 1 byte | rel_tbl_type| type of the other table in this fk |
|
||||
| | | | (same values as index_type) |
|
||||
| 0xFF | 4 bytes | rel_idx_num | index number of other index in fk |
|
||||
| | | | (or -1 if this index is not a fk) |
|
||||
| 0x00 | 4 bytes | rel_tbl_page| page number of other table in fk |
|
||||
| 0x01 | 1 byte | cascade_ups | flag indicating if updates are cascaded |
|
||||
| 0x01 | 1 byte | cascade_dels| flag indicating if deletes are cascaded |
|
||||
| ???? | 1 byte | index_type | 0x01 if index is primary, 0x02 if foreign|
|
||||
+-------------------------------------------------------------------------+
|
||||
| Iterate for the number of num_idx |
|
||||
+-------------------------------------------------------------------------+
|
||||
@@ -367,8 +375,10 @@ next_pg field.
|
||||
| Iterate while col_num != 0xffff |
|
||||
+-------------------------------------------------------------------------+
|
||||
| ???? | 2 bytes | col_num | Column number with variable length |
|
||||
| ???? | 4 bytes | arg1 | |
|
||||
| ???? | 4 bytes | arg2 | |
|
||||
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||
| | | | usage bitmask for this column. |
|
||||
| ???? | 4 bytes | free_pages | Points to a similar record as above, |
|
||||
| | | | listing pages which contain free space. |
|
||||
+-------------------------------------------------------------------------+
|
||||
|
||||
+-------------------------------------------------------------------------+
|
||||
@@ -390,7 +400,7 @@ next_pg field.
|
||||
| ???? | 2 bytes | max_cols | Max columns a row will have (deletions) |
|
||||
| ???? | 2 bytes | num_var_cols| Number of variable columns in table |
|
||||
| ???? | 2 bytes | num_cols | Number of columns in table (repeat) |
|
||||
| ???? | 4 bytes | num_idx | Number of indexes in table |
|
||||
| ???? | 4 bytes | num_idx | Number of logical indexes in table |
|
||||
| ???? | 4 bytes | num_real_idx| Number of index entries |
|
||||
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||
| | | | usage bitmask for this table. |
|
||||
@@ -425,7 +435,7 @@ next_pg field.
|
||||
| ???? | 2 bytes | col_name_len| len of the name of the column |
|
||||
| ???? | n bytes | col_name | Name of the column (UCS-2 format) |
|
||||
+-------------------------------------------------------------------------+
|
||||
| Iterate for indexes with index_type 0 or 1 (30+22 = 52 bytes) |
|
||||
| Iterate for the number of num_real_idx (30+22 = 52 bytes) |
|
||||
+-------------------------------------------------------------------------+
|
||||
| ???? | 4 bytes | ??? | |
|
||||
+-------------------------------------------------------------------------+
|
||||
@@ -434,7 +444,7 @@ next_pg field.
|
||||
| ???? | 2 bytes | col_num | number of a column (0xFFFF= none) |
|
||||
| ???? | 1 byte | col_order | 0x01 = ascendency order |
|
||||
+-------------------------------------------------------------------------+
|
||||
| ???? | 4 bytes | unknown | |
|
||||
| ???? | 4 bytes | used_pages | Points to usage bitmap for index |
|
||||
| ???? | 4 bytes | first_dp | Data pointer of the index page |
|
||||
| ???? | 1 byte | flags | See flags table for indexes |
|
||||
| ???? | 9 bytes | unknown | |
|
||||
@@ -445,12 +455,14 @@ next_pg field.
|
||||
| ???? | 4 bytes | index_num | Number of the index |
|
||||
| | | |(warn: not always in the sequential order)|
|
||||
| ???? | 4 bytes | index_num2 | Index into index cols list |
|
||||
| 0x00 | 1 byte | ??? | |
|
||||
| 0xFF | 4 bytes | ??? | |
|
||||
| 0x00 | 4 bytes | ??? | |
|
||||
| 0x04 | 2 bytes | ??? | |
|
||||
| ???? | 1 byte | primary_key | 0x01 if this index is primary |
|
||||
| ???? | 4 bytes | unknown | |
|
||||
| 0x00 | 1 byte | rel_tbl_type| type of the other table in this fk |
|
||||
| | | | (same values as index_type) |
|
||||
| 0xFF | 4 bytes | rel_idx_num | index number of other index in fk |
|
||||
| | | | (or -1 if this index is not a fk) |
|
||||
| 0x00 | 4 bytes | rel_tbl_page| page number of other table in fk |
|
||||
| 0x01 | 1 byte | cascade_ups | flag indicating if updates are cascaded |
|
||||
| 0x01 | 1 byte | cascade_dels| flag indicating if deletes are cascaded |
|
||||
| ???? | 1 byte | index_type | 0x01 if index is primary, 0x02 if foreign|
|
||||
+-------------------------------------------------------------------------+
|
||||
| Iterate for the number of num_idx |
|
||||
+-------------------------------------------------------------------------+
|
||||
@@ -460,8 +472,10 @@ next_pg field.
|
||||
| Iterate while col_num != 0xffff |
|
||||
+-------------------------------------------------------------------------+
|
||||
| ???? | 2 bytes | col_num | Column number with variable length |
|
||||
| ???? | 4 bytes | arg1 | |
|
||||
| ???? | 4 bytes | arg2 | |
|
||||
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||
| | | | usage bitmask for this column. |
|
||||
| ???? | 4 bytes | free_pages | Points to a similar record as above, |
|
||||
| | | | listing pages which contain free space. |
|
||||
+-------------------------------------------------------------------------+
|
||||
|
||||
Columns flags (not complete):
|
||||
@@ -500,6 +514,29 @@ Column Type may be one of the following (not complete):
|
||||
REPID = 0x0F /* GUID */
|
||||
NUMERIC = 0x10 /* Scaled decimal (17 bytes) */
|
||||
|
||||
Notes on reading index metadata:
|
||||
|
||||
There are 2 types of index metadata, "physical" index info (denoted by
|
||||
num_real_idx) and "logical" index info (denoted by num_idx). Normally, there
|
||||
is a 1 to 1 relationship between these 2 types of information. However there
|
||||
can be more logical index infos than physical index infos (currently only seen
|
||||
for foreign key indexes). In this situation, one or more of the logical
|
||||
indexes actually share the same underlying physical index (the index_num2
|
||||
indicates which physical index backs which logical index).
|
||||
|
||||
As noted in the previous paragraph, physical index sharing is generally only
|
||||
seen when a foreign key index has been created. When access creates a
|
||||
relationship between 2 tables with "enforce referential integrity" enabled,
|
||||
each of the tables gets an extra logical index with type 2 (foreign key).
|
||||
These logical indexes contain extra information, primarily pointers to the
|
||||
related table (rel_tbl_page) and logical index (rel_idx_num). Also, the
|
||||
rel_tbl_type value indicates which table in the relationship is the "primary"
|
||||
table (the one one from which cascaded updates/deletes flow). If the indexed
|
||||
columns for the foreign key are already indexed by another logical index in
|
||||
the table (e.g. an index which the user has explicitly created), then the
|
||||
logical foreign key index will simply share the underlying physical index
|
||||
data.
|
||||
|
||||
Notes on deleted and added columns: (sort of Jet4 specific)
|
||||
|
||||
If a fixed length column is deleted the offset_F field will contain the offsets
|
||||
|
Reference in New Issue
Block a user