The alphanumeric type (A) is straightforward: for each character the program maintains a byte of storage. There are no extra bytes at the beginning or end. The size of the field is determined by the program from a DEFINE command or from the data dictionary.
A numeric field (type N) is in the standard IEEE floating point format and is contained in 8 bytes of storage independent of the display size of the field.
A byte field (type B) can have a value from 0 through 255.
A logical field (type L) can have only two values, .TRUE. or .FALSE. Internally .TRUE. is 1 and .FALSE. is 0 and uses 1 byte of memory.
An integer field (type I) can have a value from -32768 through 32767. It is maintained in standard IEEE low byte low format and uses 2 bytes of memory. This is know as a Short integer. Signed 16-bit.
A record field (type R) can have a value from -2,147,483,648 through 2,147,483,647 . It is maintained in standard IEEE format and uses 4 bytes of memory. This field can also be thought of as being a long or double integer and can be used in that manner. This is known as a Long Integer. Signed 32-bit.
A date field (type D) is kept in a special format that corresponds to that used by Btrieve. This format is low byte day value, next byte month value and high word year value, total 4 bytes memory used. All values are kept in binary format.
A time field (type T) is kept in a special format that corresponds to that used by Btrieve. This format is low byte hundredths of seconds, next byte seconds, next byte minutes, and high byte hours, total 4 bytes memory used. All values are kept in binary format.
An F-Pointer field (type F) is a compound field. The low byte contains the type of the field being pointed to; F - standard field, C - constant, or X - expression. The high double-word is the location of the field specification within the field list segment within the program being run, for a total of 5 bytes memory used. This field type is not usable outside of TAS Professional. However, it has great use within a program and is the smallest pointer value.
A P-Pointer field (type P) is a compound field. This field is closer to the standard far pointers in C. The low double-word is the location value, the next byte is the field type (a single alpha character as listed above), next byte is the number of decimal characters, the next double-word is the internal size in bytes, and the final double-word is the display size in characters, for a total of 14 bytes memory used. The reason for the complexity of this field is so that you can pass this value to an external program (non-TAS) and know everything necessary about the field. The location value points to the actual field value in memory, not at the field list. You can add and subtract values to/from a P-Pointer field location using integers. However, all other parts of the field cannot be changed.
An AUTOINC field (type U) (New since version 7.6)
NOTE : Requires database version 6.15 or above if your databases are using version 5.10 this will not work!! This is a Btrieve or pervasive SQL type field. You should not use this type field in a codebase file.
In an attempt to modernize our programming Language we have added the AUTOINC field (type U) to TAS Professional so that you can use pure SQL calls using the SQL() in TAS Professional and to also make it so you can use other programming tools like C##, Access, Java and others to work with your data. Not that we want you to use these tools sometimes it just good to say you can.
The AUTOINC key type is a signed Intel integer that can be either two or four bytes long. Internally, AUTOINC keys are stored in Intel binary integer format, with the high-order and low-order bytes reversed within a word. The MicroKernel sorts AUTOINC keys by their absolute (positive) values, comparing the values stored in different records a word at a time from right to left. AUTOINC keys may be used to automatically assign the next highest value when a record is inserted into a file. Because the values are sorted by absolute value, the number of possible records is roughly half what you would expect given that the data type is signed.
Values that have been deleted from the file are not re-used automatically. If you indicate that you want the database engine to assign the next value by entering a zero (0) value in an insert or update, the database simply finds the highest number, adds 1, and inserts the resulting value.
You can initialize the value of a field in all or some records to zero and later add an index of type AUTOINC. This feature allows you to prepare for an AUTOINC key without actually building the index until it is needed.
When you add the index, the MicroKernel changes the zero values in each field appropriately, beginning its numbering with a value equal to the greatest value currently defined in the field, plus one. If nonzero values exist in the field, the MicroKernel does not alter them. However, the MicroKernel returns an error status code if nonzero duplicate values exist in the field.
The MicroKernel maintains the highest previously used auto-increment value associated with each open file containing an AUTOINC key. This value is established and increments only when an INSERT operation occurs for a record with ASCII zeros in the AUTOINC field. The value is used by all clients so that concurrent changes can take place, taking advantage of Key Page Concurrency.
The next AUTOINC value for a file is raised whenever any INSERT occurs that uses the previous AUTOINC value. This happens whether or not the INSERT is in a transaction or the change is committed.
However, this value may be lowered during an INSERT if all of the following are true:
The highest AUTOINC value found in the key is lower than the next AUTOINC value for the file
No other client has a pending transaction affecting the page that contains the highest AUTOINC value
The key page containing the highest AUTOINC value is not already pending by the client doing the INSERT.
In other words, only the first INSERT within a transaction can lower the next available AUTOINC value. After that, the next available AUTOINC value just keeps increasing.
An example helps clarify how an AUTOINC value may be lowered. Assume an autoincrement file exists with records 1, 2, 3 and 4. The next available AUTOINC value is 5.
Client1 begins a transaction and inserts two new records, raising the next available AUTOINC value to 7. (Client1 gets values 5 and 6). Client2 begins a transaction and also inserts two new records. This raises the next available AUTOINC value to 9. (Client 2 gets values 7 and 8).
Client1 the deletes records 4, 5, and 6. The next AUTOINC value remains the same since it is adjusted only on INSERTS. Client1 then commits. The committed version of the file now contains records 1, 2, and 3.
For Client2, the file contains records 1, 2, 3, 7, and 8 (7 and 8 are not yet committed). Client2 then inserts another record, which becomes record 9. The next available AUTOINC value is raised to 10. Client2 deletes records 3, 7, 8, and 9. For Client2, the file now contains only the committed records 1 and 2.
Next Client2 inserts another record, which becomes record 10. The next available AUTOINC value is raised to 11. The next autoincrement value is not lowered to 3 since the page containing the change has other changes pending on it.
Client2 then aborts the transaction. The committed version of the file now contains records 1, 2, and 3, but the next available AUTOINC value is still 11.
If either client inserts another record, whether in a transaction or not, the next available AUTOINC value will be lowered to 4. This occurs because all of the conditions required for lowering the value are true.
If a resulting auto-increment value is out of range, a Status Code 5 results. The database engine does not attempt to “wrap” the values and start again from zero. You may, however, insert unused values directly if you know of gaps in the autoincrement sequence where a previously inserted value has been deleted.
The following restrictions apply to AUTOINC keys:
|•||The key must be defined as unique.|
|•||The key cannot be segmented. However, an AUTOINC key can be included as an integer segment of another key, as long as the AUTOINC key has been defined as a separate, single key first, and the AUTOINC key number is lower than the segmented key number.|
|•||The key cannot overlap another key.|
|•||All keys must be ascending.|
The MicroKernel treats AUTOINC key values as follows when you insert records into a file:
If you specify a value of binary 0 for the AUTOINC key, the MicroKernel assigns a value to the key based on the following criteria:
If you are inserting the first record in the file, the MicroKernel assigns the value of 1 to the AUTOINC key.
If records already exist in the file, the MicroKernel assigns the key a value that is one number higher than the highest existing absolute value in the file.
If you specify a positive, nonzero value for the AUTOINC key, the MicroKernel inserts the record into the file and uses the specified value as the key value. If a record containing that value already exists in the file, the MicroKernel returns an error status code, and does not insert the record.