mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-18 18:22: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
|
user interface; 2 gigabytes of character storage when entering data
|
||||||
programmatically. That would mean 31 bits for length.
|
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
|
LVAL (Long Value) Pages
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
@@ -306,7 +311,7 @@ next_pg field.
|
|||||||
| ???? | 2 bytes | max_cols | Max columns a row will have (deletions) |
|
| ???? | 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_var_cols| Number of variable columns in table |
|
||||||
| ???? | 2 bytes | num_cols | Number of columns in table (repeat) |
|
| ???? | 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 | num_real_idx| Number of index entries |
|
||||||
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||||
| | | | usage bitmask for this table. |
|
| | | | usage bitmask for this table. |
|
||||||
@@ -337,14 +342,14 @@ next_pg field.
|
|||||||
| ???? | 1 byte | col_name_len| len of the name of the column |
|
| ???? | 1 byte | col_name_len| len of the name of the column |
|
||||||
| ???? | n bytes | col_name | 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) |
|
| Iterate 10 times for 10 possible columns (10*3 = 30 bytes) |
|
||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
| ???? | 2 bytes | col_num | number of a column (0xFFFF= none) |
|
| ???? | 2 bytes | col_num | number of a column (0xFFFF= none) |
|
||||||
| ???? | 1 byte | col_order | 0x01 = ascendency order |
|
| ???? | 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 |
|
| ???? | 4 bytes | first_dp | Data pointer of the index page |
|
||||||
| ???? | 1 byte | flags | See flags table for indexes |
|
| ???? | 1 byte | flags | See flags table for indexes |
|
||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
@@ -353,11 +358,14 @@ next_pg field.
|
|||||||
| ???? | 4 bytes | index_num | Number of the index |
|
| ???? | 4 bytes | index_num | Number of the index |
|
||||||
| | | |(warn: not always in the sequential order)|
|
| | | |(warn: not always in the sequential order)|
|
||||||
| ???? | 4 bytes | index_num2 | Index into index cols list |
|
| ???? | 4 bytes | index_num2 | Index into index cols list |
|
||||||
| 0x00 | 1 byte | ??? | |
|
| 0x00 | 1 byte | rel_tbl_type| type of the other table in this fk |
|
||||||
| 0xFF | 4 bytes | ??? | |
|
| | | | (same values as index_type) |
|
||||||
| 0x00 | 4 bytes | ??? | |
|
| 0xFF | 4 bytes | rel_idx_num | index number of other index in fk |
|
||||||
| 0x04 | 2 bytes | ??? | |
|
| | | | (or -1 if this index is not a fk) |
|
||||||
| ???? | 1 byte | primary_key | 0x01 if this index is primary |
|
| 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 |
|
| Iterate for the number of num_idx |
|
||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
@@ -367,8 +375,10 @@ next_pg field.
|
|||||||
| Iterate while col_num != 0xffff |
|
| Iterate while col_num != 0xffff |
|
||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
| ???? | 2 bytes | col_num | Column number with variable length |
|
| ???? | 2 bytes | col_num | Column number with variable length |
|
||||||
| ???? | 4 bytes | arg1 | |
|
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||||
| ???? | 4 bytes | arg2 | |
|
| | | | 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 | max_cols | Max columns a row will have (deletions) |
|
||||||
| ???? | 2 bytes | num_var_cols| Number of variable columns in table |
|
| ???? | 2 bytes | num_var_cols| Number of variable columns in table |
|
||||||
| ???? | 2 bytes | num_cols | Number of columns in table (repeat) |
|
| ???? | 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 | num_real_idx| Number of index entries |
|
||||||
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||||
| | | | usage bitmask for this table. |
|
| | | | usage bitmask for this table. |
|
||||||
@@ -425,7 +435,7 @@ next_pg field.
|
|||||||
| ???? | 2 bytes | col_name_len| len of the name of the column |
|
| ???? | 2 bytes | col_name_len| len of the name of the column |
|
||||||
| ???? | n bytes | col_name | Name of the column (UCS-2 format) |
|
| ???? | 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 | ??? | |
|
| ???? | 4 bytes | ??? | |
|
||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
@@ -434,7 +444,7 @@ next_pg field.
|
|||||||
| ???? | 2 bytes | col_num | number of a column (0xFFFF= none) |
|
| ???? | 2 bytes | col_num | number of a column (0xFFFF= none) |
|
||||||
| ???? | 1 byte | col_order | 0x01 = ascendency order |
|
| ???? | 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 |
|
| ???? | 4 bytes | first_dp | Data pointer of the index page |
|
||||||
| ???? | 1 byte | flags | See flags table for indexes |
|
| ???? | 1 byte | flags | See flags table for indexes |
|
||||||
| ???? | 9 bytes | unknown | |
|
| ???? | 9 bytes | unknown | |
|
||||||
@@ -445,12 +455,14 @@ next_pg field.
|
|||||||
| ???? | 4 bytes | index_num | Number of the index |
|
| ???? | 4 bytes | index_num | Number of the index |
|
||||||
| | | |(warn: not always in the sequential order)|
|
| | | |(warn: not always in the sequential order)|
|
||||||
| ???? | 4 bytes | index_num2 | Index into index cols list |
|
| ???? | 4 bytes | index_num2 | Index into index cols list |
|
||||||
| 0x00 | 1 byte | ??? | |
|
| 0x00 | 1 byte | rel_tbl_type| type of the other table in this fk |
|
||||||
| 0xFF | 4 bytes | ??? | |
|
| | | | (same values as index_type) |
|
||||||
| 0x00 | 4 bytes | ??? | |
|
| 0xFF | 4 bytes | rel_idx_num | index number of other index in fk |
|
||||||
| 0x04 | 2 bytes | ??? | |
|
| | | | (or -1 if this index is not a fk) |
|
||||||
| ???? | 1 byte | primary_key | 0x01 if this index is primary |
|
| 0x00 | 4 bytes | rel_tbl_page| page number of other table in fk |
|
||||||
| ???? | 4 bytes | unknown | |
|
| 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 |
|
| Iterate for the number of num_idx |
|
||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
@@ -460,8 +472,10 @@ next_pg field.
|
|||||||
| Iterate while col_num != 0xffff |
|
| Iterate while col_num != 0xffff |
|
||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
| ???? | 2 bytes | col_num | Column number with variable length |
|
| ???? | 2 bytes | col_num | Column number with variable length |
|
||||||
| ???? | 4 bytes | arg1 | |
|
| ???? | 4 bytes | used_pages | Points to a record containing the |
|
||||||
| ???? | 4 bytes | arg2 | |
|
| | | | 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):
|
Columns flags (not complete):
|
||||||
@@ -500,6 +514,29 @@ Column Type may be one of the following (not complete):
|
|||||||
REPID = 0x0F /* GUID */
|
REPID = 0x0F /* GUID */
|
||||||
NUMERIC = 0x10 /* Scaled decimal (17 bytes) */
|
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)
|
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
|
If a fixed length column is deleted the offset_F field will contain the offsets
|
||||||
|
Reference in New Issue
Block a user