Literal pool area

<< Click to Display Table of Contents >>

Navigation:  Application development > Filtering records >

Literal pool area

Previous pageReturn to chapter overviewNext page

The literal pool is used to store the field names pointed to by each field node and the constant values pointed to by each constant node. Field names contain literals. Constant values must be represented in BDE logical types only.

For example, the following Boolean condition is represented as an expression tree parameter, and then as a chart:

CUST_NO <= 1500 AND CUST_NO >= 1300

Expression Tree

The following example assumes that the compiler allocates consecutively declared variables in physically contiguous memory:

 
static const char szTblName[] = "cust";     // Name of the table
static const char szTblType[] = szDBASE;    // Type of table
static const char szField[]   = "CUST_NO";  // Name for the first field node
static const char szField2[]  = "CUST_NO";  // Name for the second field node
static const DFLOAT fConst    = 1500.0;     // Value of the first constant node
static const DFLOAT fConst2   = 1300.0;     // Value of the second constant node

 

void
Filter (void)
{
    hDBIDb          hDb = 0;            // Handle to the database.
    hDBICur         hCur = 0;           // Handle to the table.
    DBIResult       rslt;               // Return value from IDAPI functions.
    pBYTE           pcanExpr;           // Structure containing filter info.
    hDBIFilter      hFilter;            // Filter handle.
    UINT16          uSizeNodes;         // Size of the nodes in the tree.
    UINT16          uSizeCanExpr;       // Size of the header information.
    UINT32          uSizeLiterals;      // Size of the literals.
    UINT32          uTotalSize;         // Total size of the filter expression.
    UINT32          uNumRecs = 10;      // Number of records to display.
    CANExpr         canExp;             // Contains the header information.
    struct {
        CANBinary MainNode;
        CANBinary BinaryNode1;
        CANField  FieldNode1;
        CANConst  ConstantNode1;
        CANBinary BinaryNode2;
        CANField  FieldNode2;
        CANConst  ConstantNode2;
    }
    Nodes = {                           // Nodes of the filter tree.
    {
        // Offset 0
        nodeBINARY,                     // canBinary.nodeClass
        canAND,                         // canBinary.canOp
        sizeof(Nodes.MainNode),         // canBinary.iOperand1
        sizeof(Nodes.MainNode)
          + sizeof(Nodes.BinaryNode1)
          + sizeof(Nodes.FieldNode1)
          + sizeof(Nodes.ConstantNode1),// canBinary.iOperand2
                                        //   Offsets in the Nodes array
    },
    {
        // Offset sizeof(Nodes.MainNode)
        nodeBINARY,                     // canBinary.nodeClass
        canLE,                          // canBinary.canOp
        sizeof(Nodes.MainNode)
          + sizeof(Nodes.BinaryNode1),  // canBinary.iOperand1
        sizeof(Nodes.MainNode)
          + sizeof(Nodes.BinaryNode1)
          + sizeof(Nodes.FieldNode1),   // canBinary.iOperand2
                                        //   Offsets in the Nodes array
    },
    {
        // Offset sizeof(Nodes.MainNode) + sizeof(Nodes.BinaryNode1)
        nodeFIELD,                      // canField.nodeClass
        canFIELD,                       // canField.canOp
        1,                              // canField.iFieldNum
        0 ,                             // canField.iNameOffset: szField is the
                                        // literal at 0 (start of literal pool)
    },
    {
        // Offset sizeof(Nodes.MainNode) + sizeof(Nodes.BinaryNode1)
        //   + sizeof(Nodes.FieldNode1)
        nodeCONST,                      // canConst.nodeClass
        canCONST,                       // canConst.canOp
        fldFLOAT,                       // canConst.iType
        sizeof(fConst),                 // canConst.iSize
        sizeof(szField),                // canConst.iOffset: fConst is the
                                        // literal at offset sizeof(szField)
    },
    {
        // Offset sizeof(Nodes.MainNode) + sizeof(Nodes.BinaryNode1)
        //   + sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1)
        nodeBINARY,                     // canBinary.nodeClass
        canGE,                          // canBinary.canOp
        sizeof(Nodes.MainNode)
          + sizeof(Nodes.BinaryNode1)
          + sizeof(Nodes.FieldNode1)
          + sizeof(Nodes.ConstantNode1)
          + sizeof(Nodes.BinaryNode2),  // canBinary.iOperand1
        sizeof(Nodes.MainNode)
          + sizeof(Nodes.BinaryNode1)
          + sizeof(Nodes.FieldNode1)
          + sizeof(Nodes.ConstantNode1)
          + sizeof(Nodes.BinaryNode2)
          + sizeof(Nodes.FieldNode2),   // canBinary.iOperand2
                                        //   Offsets in the Nodes array
    },
    {
        // Offset sizeof(Nodes.MainNode) + sizeof(Nodes.BinaryNode1)
        //   + sizeof(Nodes.FieldNode1) + sizeof(Nodes.ConstantNode1)
        //   + sizeof(Nodes.BinaryNode2)
        nodeFIELD,                      // canField.nodeClass
        canFIELD,                       // canField.canOp
        2,                              // canField.iFieldNum
        sizeof(szField)+sizeof(fConst), // canField.iNameOffset: szField2 is
                                        //   the literal at sizeof(fConst)
                                        //   + size of the first field
    },
    {
        // Offset sizeof(Nodes.MainNode) + sizeof(Nodes.BinaryNode1)
        //   + sizeof(Nodes.FieldNode1) + sizeof(Nodes.FieldNode1)
        //   + sizeof(Nodes.BinaryNode2) + sizeof(Nodes.FieldNode2)
        nodeCONST,                      // canConst.nodeClass
        canCONST,                       // canConst.canOp
        fldFLOAT,                       // canConst.iType
        sizeof(fConst2),                // canConst.iSize
        sizeof(szField)
          + sizeof(fConst)
          + sizeof(szField2),           // canConst.iOffset: fconst is the
                                        // literal at sizeof(fConst)+size of
                                        //   the first field + second field
    }};

 

Chart

The chart below represents the same Boolean expression: CUST_NO <= 1500 AND CUST_NO >= 1300
(Note that the offsets are shown in parentheses.)

Header:

         -----------------------------------------------------------

Binary node:

 

AND (0)

 

Binary nodes:

LE (12)

GE (50)

Constant & field nodes:

FIELD (24)

CONST (36)

FIELD (62)

CONST (74)

Literal / constant pool:

CUST_NO (0)

1500 (8)

CUST_NO (16)

1300 (24)