[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.").
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.
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
};
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;
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
};
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
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
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 )
This structure represents specific information required by grouping operators, i.e., project_list_ elements used for grouping.
typedef struct tagDBGROUPINFO {
LCID lcid;
} DBGROUPINFO ;
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;
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;
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;
tyepdef struct tagDBSETFUNC {
DWORD dwSetQuantifier;
} DBSETFUNC;
#define DBSETFUNC_NONE = 0x0
#define DBSETFUNC_ALL = 0x1
#define DBSETFUNC_DISTINCT = 0x2
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;
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;
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.
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;
DBGUID_LIKE_SQL
DBGUID_LIKE_DOS
DBGUID_LIKE_OFS
DBGUID_LIKE_MAPI