DBCOMMANDTREE Structures

[This is preliminary documentation and subject to change.]

This structure is used for each DML or DDL node in an OLE DB command tree. Many operations create a binding environment. For example, a DBOP_select operation has two inputs: a table and a Boolean predicate. By virtue of the "select" operation, the table becomes the binding environment for the predicate. That means that the predicate may freely reference column names defined in the table. Note that not all bindings must come from the nearest table operation. For example, there might be multiple table operations within an "exist" expression, and any predicate may reference a column defined outside the "exist" expression (In SQL, this is called a "correlated subquery.").

DBCOMMANDTREE Structure

This is the primary data structure used to represent any node in an OLE DB tree as described in the Data Manipulation and Data Definition Operator Sections above.

typedef WORD DBCOMMANDOP;
 
typedef struct tagDBCOMMANDTREE {
    DBCOMMANDOP op;      // Operator identifier (2 bytes)
    WORD            wKind;   // Discriminator for the following union (2 bytes)
    struct tagDBCOMMANDTREE * pctFirstChild;  // Pointer to first child (4 bytes)
    struct tagDBCOMMANDTREE * pctNextSibling; // Pointer to sibling (4 bytes)
    union {     // Union direclty represents fields that fit within 8 bytes.
            // Comments list DBVALUEKIND and DBTYPE corresponding to each field.
        BOOL                    fValue;       // DBVALUEKIND_BOOL      (DBTYPE_BOOL)
        unsigned char           uchValue;     // DBVALUEKIND_UI1       (DBTYPE_UI1)
        signed char             schValue;     // DBVALUEKIND_I1        (DBTYPE_I1)
        unsigned short          usValue;      // DBVALUEKIND_UI2       (DBTYPE_UI2)
        short                   sValue;       // DBVALUEKIND_I2        (DBTYPE_I2)
        LPWSTR                  pwszValue;    // DBVALUEKIND_WSTR      (DBTYPE_WSTR)
        LONG                    lValue;       // DBVALUEKIND_I4        (DBTYPE_I4)    
        ULONG                   ulValue;      // DBVALUEKIND_UI4       (DBTYPE_UI4)
        float                   flValue;      // DBVALUEKIND_R4        (DBTYPE_R4)
        double                  dblValue;     // DBVALUEKIND_R8        (DBTYPE_R8)
        CY                      cyValue;      // DBVALUEKIND_CY        (DBTYPE_CY)
        DATE                    dateValue;    // DBVALUEKIND_DATE      (DBTYPE_DATE)
        DBDATE                  dbdateValue;  // DBVALUEKIND_DBDATE    (DBTYPE_DBDATE)
        DBTIME                  dbtimeValue;  //    DBVALUEKIND_DBTIME (DBTYPE_DBTIME)
        SCODE                   scodeValue;   // DBVALUEKIND_ERROR     (DBTYPE_ERROR)
        __int64                 llValue;      // DBVALUEKIND_I8        (DBTYPE_I8)
        unsigned __int64        ullValue;     // DBVALUEKIND_UI8       (DBTYPE_UI8)
        BSTR     *              pbstrValue;   // DBVALUEKIND_BSTR          (DBTYPE_BSTR)
        ICommand     *          pCommand;     // DBVALUEKIND_COMMAND   (DBTYPE_IUNKNOWN)
        IDispatch *             pDispatch;    // DBVALUEKIND_IDISPATCH (DBTYPE_IDISPATCH)
        IMoniker     *          pMoniker;     // DBVALUEKIND_MONIKER   (DBTYPE_MONIKER)
        IRowset *               pRowset;      // DBVALUEKIND_ROWSET    (DBTYPE_ROWSET)
        IUnknown     *          pUnknown;     // DBVALUEKIND_IUNKNOWN  (DBTYPE_IUNKNOWN)
        DBBYGUID     *       pdbbygdValue;    // DBVALUEKIND_BYGUID
        DBCOLUMNDESC*        pcoldescValue;   // DBVALUEKIND_COLDESC
        DBID *               pdbidValue;      // DBVALUEKIND_ID
        DBLIKE *             pdblikeValue;    // DBVALUEKIND_LIKE
        DBCONTENT *          pdbcntntValue;   // DBVALUEKIND_CONTENT
        DBCONTENTVECTOR *    pdbcntntvcValue; // DBVALUEKIND_CONTENTVECTOR
        DBCONTENTPROXIMITY *    pdbcntntproxValue;    // DBVALUEKIND_CONTENTPROXIMITY
        DBGROUPINFO *           pdbgrpinfValue;  // DBVALUEKIND_GROUPINFO
        DBPARAMETER *           pdbparamValue;   // DBVALUEKIND_PARAMETER
        DBPROPSET *             pdbpropValue;    // DBVALUEKIND_PROPERTY
        DBSETFUNC *             pdbstfncValue;   // DBVALUEKIND_SETFUNC
        DBSORTINFO *            pdbsrtinfValue;  // DBVALUEKIND_SORTINFO
        DBTEXT *                pdbtxtValue;     // DBVALUEKIND_TEXT
        DBVECTOR     *          pdbvectorValue;  // DBVALUEKIND_VECTOR | *
        SAFEARRAY *             parrayValue;     // DBVALUEKIND_ARRAY | *
        VARIANT *               pvarValue;       // DBVALUEKIND_VARIANT  (DBTYPE_VARIANT)
        GUID     *              pGuid;           // DBVALUEKIND_GUID     (DBTYPE_GUID)
        BYTE     *              pbValue;         // DBVALUEKIND_BYTES    (DBTYPE_BYTES)
        char     *              pzValue;         // DBVALUEKIND_STR      (DBTYPE_STR)
        DBNUMERIC *             pdbnValue;       // DBVALUEKIND_NUMERIC  (DBTYPE_NUMERIC)
        DBTIMESTAMP *           pdbtsValue;      // DBVALUEKIND_DBTIMESTAMP (DBTYPE_DBTIMESTAMP)
        void *                  pvValue;         // a generic DBVALUEKIND_BYREF
    } value;
    HRESULT     hrError;     // Error indicator, details in Extended Error info (4 bytes)
} DBCOMMANDTREE;
 

The typical size of a DBCOMMANDTREE node is 24 bytes, however, operators may store some specific information inside the value field of the node. For programming convenience, the union field includes branches representing some common types that can fit within 8 bytes. Variable-length types are referenced via a pointer to the corresponding structure (e.g., DBTEXT). The discriminator for the union is of type WORD rather than DBVALUEKIND so that it is possible to store node values such as DBVALUEKIND_VECTOR | DBVALUEKIND_GUID, DBVALUEKIND_BYREF | DBVALUEKIND_UI4, or DBVALUEKIND_SAFEARRAY | DBVALUEKIND_I4;

The pwszValue field is just a string; its interpretation is left to the provider. In other words, the consumer must understand the provider's method of name resolution. For command components "passed-through" to another provider, it is left to that bottom provider to interpret the string.

The pMoniker field is used for unresolved linked objects, in particular tables and functions.

The pRowset field is used to reference a currently open rowset as input for a command. Most providers will fail if some IPersist method is invoked while the command tree refers to an open rowset.

The pCommand field references another command object as input for a command. Most providers will fail if some IPersist method is invoked while the command tree refers to a command object that does not support monikers.

DBVALUEKIND Enumerated Type

This enumerated type is used to discriminate the union field inside a DBCOMMANDTREE struct. For programming convenience, the values in this enumeration correspond exactly to the OLE Automation VARENUM and OLE DB DBTYPE (see Appendix A for description) enumerations. The comments associated with each enumeration value represents the type and branch of the union type inside the command structure containing the value. Nodes that do not assign a value to the union member should assign a DBVALUEKIND_EMPTY to wKind.

enum DBVALUEKIND {
    // List of structure values     union contains a pointer to:
    DBVALUEKIND_BYGUID            = 256.                            // DBBYGUID struct
    DBVALUEKIND_COLDESC            = DBVALUEKIND_BYGUID + 1,        // DBCOLDESC struct     DBVALUEKIND_ID                = DBVALUEKIND_COLDESC + 1,        // DBID struct
    DBVALUEKIND_CONTENT            = DBVALUEKIND_ID + 1,            // DBCONTENT struct
    DBVALUEKIND_CONTENTVECTOR     = DBVALUEKIND_CONTENT + 1,        // DBCONTENTVECTOR struct
    DBVALUEKIND_GROUPINFO        = DBVALUEKIND_CONTENTVECTOR + 1,    // DBGROUPINFO struct
    DBVALUEKIND_PARAMETER        = DBVALUEKIND_GROUPINFO + 1,        // DBPARAMETER struct
    DBVALUEKIND_PROPERTY            = DBVALUEKIND_PARAMETER + 1,        // DBPROPERTY struct
    DBVALUEKIND_SETFUNC            = DBVALUEKIND_PROPERTY + 1,        // DBSETFUNC struct
    DBVALUEKIND_SORTINFO            = DBVALUEKIND_SETFUNC + 1,        // DBSORTINFO struct
    DBVALUEKIND_TEXT                = DBVALUEKIND_SORTINFO + 1,        // DBTEXT struct
 
    // List of OLE interface pointer values
    DBVALUEKIND_COMMAND            = DBVALUEKIND_TEXT + 1,            // pCommand value
    DBVALUEKIND_MONIKER            = DBVALUEKIND_COMMAND + 1,        // pMoniker value
    DBVALUEKIND_ROWSET            = DBVALUEKIND_MONIKER + 1,        // pRowset value
    DBVALUEKIND_LIKE            = DBVALUEKIND_ROWSET + 1,        // DBLIKE struct
    DBVALUEKIND_CONTENTPROXIMITY    =    DBVALUEKIND_LIKE + 1,    // DBCONTENTPROXIMITY structure
    DBVALUEKIND_IDISPATCH        = 9,                                // pDispatch value
    DBVALUEKIND_IUNKNOWN            = 13,                            // pUnknown value
 
    // List of OLE DB type values
    DBVALUEKIND_EMPTY            = 0,                                // No value assigned to
                                                                // the union
    DBVALUEKIND_NULL                = 1,                                // NULL value
    DBVALUEKIND_I2                = 2,                                // sValue
    DBVALUEKIND_I4                = 3,                                // lValue
    DBVALUEKIND_R4                = 4,                                // flValue
    DBVALUEKIND_R8                = 5,                                // dblValue
    DBVALUEKIND_CY                = 6,                                // cyValue
    DBVALUEKIND_DATE                = 7,                                // dateValue
    DBVALUEKIND_BSTR                = 8,                                // pbstrValue
    
    DBVALUEKIND_ERROR            = 10,                            // scodeValue;
    DBVALUEKIND_BOOL                = 11,                            // fValue 
    DBVALUEKIND_VARIANT            = 12,                            // pvarValue to an OLE
                                                                // Aut. variant
 
    DBVALUEKIND_VECTOR            = 0x1000,                        // pdbvectorValue
    DBVALUEKIND_ARRAY            = 0x2000,                        // parrayValue
    DBVALUEKIND_BYREF            = 0x4000,                        // pvValue
 
    DBVALUEKIND_I1                = 16,                            // bValue 
    DBVALUEKIND_UI1                = 17,                            // bValue
    DBVALUEKIND_UI2                = 18,                            // sValue
    DBVALUEKIND_UI4                = DBVALUEKIND_UI2 + 1,            // ulValue
    DBVALUEKIND_I8                = DBVALUEKIND_UI4 + 1,            // llValue
    DBVALUEKIND_UI8                = DBVALUEKIND_UI8 + 1,            // ullValue
    DBVALUEKIND_GUID                = 72,                            // pGuid
 
    DBVALUEKIND_BYTES            = 128,                            // pbValue
    DBVALUEKIND_STR                = 129,                            // pszValue
    DBVALUEKIND_WSTR                = DBVALUEKIND_STR + 1,            // pwszValue
    DBVALUEKIND_NUMERIC            = DBVALUEKIND_WSTR + 1            // pdbnValue
    DBVALUEKIND_DBDATE            = DBVALUEKIND_NUMERIC + 2        // dbdateValue
    DBVALUEKIND_DBTIME            = DBVALUEKIND_DBDATE + 1                // dbtimeValue
    DBVALUEKIND_DBTIMESTAMP        = DBVALUEKIND_DBTIME + 1                // pdbtsValue
};
 

DBBYGUID Structure

tyepdef struct tagDBBYGUID { 
    GUID      guid;      // this node's GUID
    ULONG     cbInfo;    // size of the data in pbInfo
    BYTE *    pbInfo;    // extra node information, provider-specific
} DBBYGUID;
 

DBID Structure

This structure encapsulates various ways of identifying a database object. It is used by nodes that need to represent a column name, i.e., column_name, index_name, table_name, schema_name, catalog_name. The DBID struct is also used to define bindings.

typedef struct  tagDBID {
    union {
        GUID guid;
        GUID *pguid;
    } uGuid;
    DBKIND eKind;
    union {
        LPWSTR pwszName;
        ULONG ulPropid;
    } uName;
} DBID;
 
typedef DWORD DBKIND;
 
enum DBKINDENUM {
    DBKIND_GUID_NAME = 0,  // use the guid and pwszName members
    DBKIND_GUID_PROPID,    // use the guid and ulPropid members
    DBKIND_NAME,           // use only the pwszName member, ignore the
                           // uGuid member
    DBKIND_PGUID_NAME,     // use the pGuid and pwszName members
    DBKIND_PGUID_PROPID,   // use the pGuid and ulPropid members
    DBKIND_PROPID,         // use only the ulPropid member, ignore the
                           // uGuid member
    DBKIND_GUID,           // use only the guid member, ignore the
};
 

DBCONTENT Structure

This structure represents specific information required by the DBOP_content operator.

typedef struct tagDBCONTENT {
    LPWSTR    pwszPhrase;          // text
    DWORD     dwGenerateMethod;    // exact, prefix, stemmed
    LONG      lWeight;             // weight of node
    LCID      lcid;                // locale
} DBCONTENT;
 
#define GENERATE_METHOD_EXACT      ( 0 )    // size is 4
#define GENERATE_METHOD_PREFIX     ( 1 )    // size is 4
#define GENERATE_METHOD_INFLECT    ( 2 )    // size is 4
 

DBCONTENTVECTOR Structure

This structure represents specific information required by the DBOP_content_vector_or operator.

typedef struct tagDBCONTENTVECTOR {
    DWORD  dwRankingMethod;        // jaccard, cosine, etc.
    LONG   lWeights;             // node weight
} DBCONTENTVECTOR ;
 
// Ranking methods:
#define VECTOR_RANK_MIN        ( 0 )    // size is 4
#define VECTOR_RANK_MAX        ( 1 )    // size is 4
#define VECTOR_RANK_INNER      ( 2 )    // size is 4
#define VECTOR_RANK_DICE       ( 3 )    // size is 4
#define VECTOR_RANK_JACCARD    ( 4 )    // size is 4
 

DBCONTENTVECTORPROXIMITY Structure

This structure represents specific information required by the DBOP_content_proximity operator.

typedef struct  tagDBCONTENTPROXIMITY    {
    DWORD dwProximityUnit;        // words, paras, chapters etc.
    ULONG ulProximityDistance;    // how near is "near"?
    LONG lWeight;                 // weight of the proximity node
}    DBCONTENTPROXIMITY;
 
// Proximity Units
#define PROXIMITY_UNIT_WORD         ( 0 )
#define PROXIMITY_UNIT_SENTENCE     ( 1 )
#define PROXIMITY_UNIT_PARAGRAPH    ( 2 )
#define PROXIMITY_UNIT_CHAPTER      ( 3 )
 

DBGROUPINFO Structure

This structure represents specific information required by grouping operators, i.e., project_list_ elements used for grouping.

typedef struct tagDBGROUPINFO {
    LCID        lcid;
} DBGROUPINFO ;
 

DBLIKE Structure

This structure represents specific information required by DBOP_like operator.

typedef struct  tagDBLIKE    {
    LONG lWeight;        // weight on the dbop_like node
    GUID guidDialect;    // system to use for "likeness". E.g. Reg. Ex.
}    DBLIKE;
 

DBPARAMETER Structure

This structure is used to define values for scalar parameters. Note that there is no entry for ordinal. The assumption is that the ordinal will be determined by the provider after evaluating the tree as a whole, and not by assigning a specific value to an individual member within the tree. Consumers can determine the ordinal based on the name using ICommandWithParameters::MapParameterNames.

typedef struct tagDBPARAMETER {
    LPWSTR            pwszName;        // parameter name
    ITypeInfo *        pTypeInfo;        // if not a null pointer, type is described
                                    // by the ITypeInfo
    DBNUMERIC *        pNum;            // Structure describing the
                                    // precision, scale and value of
                                    // the numeric value (See Appx A).
    ULONG            cbMaxLength;        // the maximum length of the
                                    // parameter
    DBPARAMFLAGS        dwFlags;            // bitmask describing parameter
                                    // characteristics
    DBTYPE            wType;            // type of the parameter
} DBPARAMETER;
 

DBPROPERTY Structure

This structure is used to define values for properties. For example, DDL commands will use it to define a default value for a column via the DB_PROPERTY_DEFAULT_VALUE property.

typedef struct tagDBPROPERTY {
    GUID       guid;      // the guid for the property
    VARIANT    vValue;    // the value of the property
} DBPROPERTY;
 

DBSETFUNC Structure

tyepdef struct tagDBSETFUNC {
    DWORD    dwSetQuantifier;
}  DBSETFUNC;
 
#define DBSETFUNC_NONE        = 0x0
#define DBSETFUNC_ALL         = 0x1
#define DBSETFUNC_DISTINCT    = 0x2
 

DBSORTINFO Structure

This structure stores the order in which a column will be sorted (i.e., ascending or descending). This information is stored inside a sort_list_element node.

typedef struct  tagDBSORTINFO {
    BOOL        fDesc;    // TRUE = asc, FALSE = desc
    LCID        lcid;
} DBSORTINFO;
 

DBTEXT Structure

This structure is used by the DBOP_text_command node. It stores the dialect that should be used to interpret the string stored in pwszText. The error locator is filled in by the provider, i.e., the first offending token is indicated as index into the text array, together with its length.

typedef struct tagDBTEXT {
    LPWSTR    pwszText;
    ULONG     ulErrorLocator; //set by validation routines
    ULONG     ulTokenLength;  //length of offending token
    GUID      guidDialect;
} DBTEXT;
 

Collection of GUIDs for the Command Text Node

DBGUID_SQL92
DBGUID_DBSQL       // This covers SQL used by OLE DB and ODBC.
DBGUID_TSQL
DBGUID_ACCESSSQL
 

To determine what dialects a provider supports, a consumer calls IDBInfo::GetPropertyInfo for the DBPROP_SQLDIALECTS property.

Command Node Example

The following is a sample helper function to allocate a new DBCOMMANDTREE structure.

DBCOMMANDTREE* PctAllocNode(
    DBOP op,
    DBVALUEKIND eKind,
    ULONG cbValueSize
    )
    {
    DBCOMMANDTREE* pct;
    //get the OLE IMalloc interface
    IMalloc* pim;
    HRESULT hr = CoGetMalloc(MEMCTX_TASK, &pim);
    if (FAILED(hr))
        return NULL;
 
    // Allocate fixed size part of the node
    pct = (DBCOMMANDTREE*)pim->Alloc((sizeof DBCOMMANDTREE));
 
    //initialize fields
    pct->op = op;
    pct->pctFirstChild = NULL;
    pct->pctNextSibling = NULL;
    pct->hrError = S_OK;
    pct->dwKind = eKind;
 
    // Allocate variable size part of the node 
    if ( 0 != cbValueSize )
        pct.value.pvValue = (void *) pim->Alloc(cbValueSize);    
 
    //Initialize value space
    memset(pct->value.pvValue, cbValueSize, 0);
 
    return pct;
    }
 

The following is sample code illustrating how to set up a condition subtree representing content search restriction. The condition searches for the ocurrence of the word "Database" within a column named Text.

DBCOMMANDTREE *pct1, pct2;
DBCONTENT* pdbc;
 
//Allocate content node
pct1 = PctAllocNode(DBOP_content, DBVALUEKIND_CONTENT, (sizeof DBCONTENT));
 
//set up value field
pdbc = (DBCONTENT*)(pct1->value.pvValue);
pdbc->dwGenerateMethod = GENERATE_METHOD_PREFIX;
pdbc->lWeight = 200;
pdbc->lcid = DEFAULT_LCID;
pdbc->pwszPhrase = L"Database";
 
//allocate column node
pct2 = PctAllocNode(DBOP_simple_name, DBVALUEKIND_WSTR,
    (sizeof LPWSTR));
pct2->value.pwszValue = L"Text";
 
//Make the column node a child of the Content node
pct1->pctFirstChild = pct2;
 

Collection of GUIDs for the "like" Operator

DBGUID_LIKE_SQL
DBGUID_LIKE_DOS
DBGUID_LIKE_OFS
DBGUID_LIKE_MAPI