727 lines
22 KiB
C
727 lines
22 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (C) 1997-2001 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
WQLNODE.H
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
WQL Parse Node Definitions
|
||
|
|
||
|
History:
|
||
|
|
||
|
raymcc 29-Sep-97 Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _WQLNODE_H_
|
||
|
#define _WQLNODE_H_
|
||
|
|
||
|
|
||
|
#define WQL_FLAG_ALIAS 0x1
|
||
|
#define WQL_FLAG_TABLE 0x2
|
||
|
#define WQL_FLAG_ASTERISK 0x4
|
||
|
#define WQL_FLAG_DISTINCT 0x8
|
||
|
#define WQL_FLAG_ALL 0x10
|
||
|
#define WQL_FLAG_COUNT 0x20
|
||
|
#define WQL_FLAG_CONST 0x40
|
||
|
#define WQL_FLAG_COLUMN 0x80
|
||
|
#define WQL_FLAG_COMPLEX_NAME 0x100
|
||
|
#define WQL_FLAG_FUNCTIONIZED 0x200
|
||
|
#define WQL_FLAG_ARRAY_REF 0x400
|
||
|
#define WQL_FLAG_UPPER 0x800
|
||
|
#define WQL_FLAG_LOWER 0x1000
|
||
|
#define WQL_FLAG_FIRSTROW 0x2000
|
||
|
#define WQL_FLAG_CONST_RANGE 0x4000
|
||
|
#define WQL_FLAG_SORT_ASC 0x8000
|
||
|
#define WQL_FLAG_SORT_DESC 0x10000
|
||
|
#define WQL_FLAG_AGGREGATE 0x20000
|
||
|
#define WQL_FLAG_NULL 0x40000
|
||
|
|
||
|
#define WQL_FLAG_INNER_JOIN 1
|
||
|
#define WQL_FLAG_LEFT_OUTER_JOIN 2
|
||
|
#define WQL_FLAG_RIGHT_OUTER_JOIN 3
|
||
|
#define WQL_FLAG_FULL_OUTER_JOIN 4
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode
|
||
|
//
|
||
|
// Base node type for all parser output.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
struct SWQLNode
|
||
|
{
|
||
|
DWORD m_dwNodeType;
|
||
|
SWQLNode *m_pLeft;
|
||
|
SWQLNode *m_pRight;
|
||
|
|
||
|
SWQLNode() { m_pLeft = 0; m_pRight = 0; m_dwNodeType = 0; }
|
||
|
virtual ~SWQLNode() { delete m_pLeft; delete m_pRight; }
|
||
|
virtual void DebugDump() = 0;
|
||
|
};
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLTypedConst
|
||
|
//
|
||
|
// Typed constant container (similar to OA VARIANT).
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
union UWQLTypedConst
|
||
|
{
|
||
|
LPWSTR m_pString; // VT_LPWSTR for WQL_TOK_QSTRING and WQL_TOK_PROMPT
|
||
|
LONG m_lValue; // VT_LONG
|
||
|
double m_dblValue; // VT_DOUBLE
|
||
|
BOOL m_bValue; // VT_BOOL, use TRUE/FALSE (not VARIANT_TRUE, VARIANT_FALSE)
|
||
|
};
|
||
|
|
||
|
struct SWQLTypedConst
|
||
|
{
|
||
|
DWORD m_dwType; // A VT_ type
|
||
|
UWQLTypedConst m_Value; // One of the union fields
|
||
|
bool m_bPrompt; // Only true if token was WQL_TOK_PROMPT
|
||
|
|
||
|
SWQLTypedConst();
|
||
|
SWQLTypedConst(SWQLTypedConst &Src) { m_dwType = VT_NULL; *this = Src; }
|
||
|
SWQLTypedConst & operator = (SWQLTypedConst &Src);
|
||
|
~SWQLTypedConst() { Empty(); }
|
||
|
void Empty();
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
struct SWQLConstList
|
||
|
{
|
||
|
CFlexArray m_aValues; // ptrs to SWQLTypedConst
|
||
|
|
||
|
SWQLConstList() {}
|
||
|
SWQLConstList(SWQLConstList &Src) { *this = Src; }
|
||
|
SWQLConstList & operator = (SWQLConstList & Src);
|
||
|
~SWQLConstList() { Empty(); }
|
||
|
void Add(SWQLTypedConst *pTC) { m_aValues.Add(pTC); }
|
||
|
void Empty();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
struct SWQLQualifiedNameField
|
||
|
{
|
||
|
LPWSTR m_pName; // Name
|
||
|
BOOL m_bArrayRef; // TRUE if this is an array reference
|
||
|
DWORD m_dwArrayIndex; // If <m_bArrayRef == TRUE> this is the array index
|
||
|
|
||
|
SWQLQualifiedNameField() { m_pName = 0; m_bArrayRef = 0; m_dwArrayIndex = 0; }
|
||
|
SWQLQualifiedNameField(SWQLQualifiedNameField &Src) { m_pName = 0; *this = Src; }
|
||
|
SWQLQualifiedNameField & operator = (SWQLQualifiedNameField &Src);
|
||
|
~SWQLQualifiedNameField() { Empty(); }
|
||
|
void Empty() { delete [] m_pName; }
|
||
|
};
|
||
|
|
||
|
struct SWQLQualifiedName
|
||
|
{
|
||
|
CFlexArray m_aFields; // [0] = left most, last entry is column
|
||
|
|
||
|
SWQLQualifiedName() {}
|
||
|
SWQLQualifiedName(SWQLQualifiedName &Src) { *this = Src; }
|
||
|
SWQLQualifiedName & operator = (SWQLQualifiedName &Src);
|
||
|
~SWQLQualifiedName() { Empty(); }
|
||
|
|
||
|
int GetNumNames() { return m_aFields.Size(); }
|
||
|
|
||
|
const LPWSTR GetName(int nIndex)
|
||
|
{
|
||
|
return (LPWSTR) ((SWQLQualifiedNameField*) m_aFields[nIndex])->m_pName;
|
||
|
}
|
||
|
|
||
|
int Add(SWQLQualifiedNameField *pQN) { return m_aFields.Add(pQN); }
|
||
|
void Empty();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
#define WQL_TOK_BASE 100
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_Select
|
||
|
//
|
||
|
// This is the root of the parse tree or the root of a subselect.
|
||
|
//
|
||
|
// SWQLNode_Select
|
||
|
// / \
|
||
|
// SWQLNode_TableRefs SWQLNode_WhereClause
|
||
|
// / \ / \
|
||
|
// x x x x
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_Select (WQL_TOK_BASE + 1)
|
||
|
|
||
|
|
||
|
|
||
|
struct SWQLNode_Select : SWQLNode
|
||
|
{
|
||
|
// Left Node is of type SWQLNode_TableRefs
|
||
|
// Right Node is of type SWQLNode_WhereClause
|
||
|
|
||
|
int m_nStPos;
|
||
|
int m_nEndPos;
|
||
|
|
||
|
SWQLNode_Select() : m_nStPos(-1), m_nEndPos(-1) { m_dwNodeType = TYPE_SWQLNode_Select; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_TableRefs
|
||
|
//
|
||
|
// This contains everything prior to the WHERE clause: the target
|
||
|
// column list and the FROM clause.
|
||
|
//
|
||
|
// Also contains the SELECT type, i.e., ALL vs. DISTINCT vs. COUNT.
|
||
|
//
|
||
|
// SWQLNode_TableRefs
|
||
|
// / \
|
||
|
// SWQLNode_ColumnList SWQLNode_FromClause
|
||
|
//
|
||
|
// In all cases, SWQLNode_ColumnList is present. Note that if the
|
||
|
// user did a "select *...", then the SWQLNode_ColumnList will only
|
||
|
// have a single column in it clearly marked as an asterisk. If
|
||
|
// a "select count(...) " was done, then m_nSelectType is set to
|
||
|
// WQL_FLAG_COUNT and the SWQLNode_ColumnList will have a single
|
||
|
// column in it, whether an * or a qualified name.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_TableRefs (WQL_TOK_BASE + 2)
|
||
|
|
||
|
struct SWQLNode_TableRefs : SWQLNode
|
||
|
{
|
||
|
// Left Node is SWQLNode_ColumnList
|
||
|
// Right Node is SWQLNode_FromClause
|
||
|
|
||
|
int m_nSelectType; // WQL_FLAG_ALL means ALL was used.
|
||
|
// WQL_FLAG_DISTINCT means DISTINCT was used.
|
||
|
// WQL_FLAG_COUNT means COUNT was used.
|
||
|
|
||
|
SWQLNode_TableRefs()
|
||
|
{ m_nSelectType = WQL_FLAG_ALL;
|
||
|
m_dwNodeType = TYPE_SWQLNode_TableRefs;
|
||
|
}
|
||
|
|
||
|
~SWQLNode_TableRefs() {}
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_ColumnList
|
||
|
//
|
||
|
// This contains the selected list of columns.
|
||
|
//
|
||
|
// SWQLNode_ColumnList
|
||
|
// / \
|
||
|
// NULL NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_ColumnList (WQL_TOK_BASE + 3)
|
||
|
|
||
|
struct SWQLNode_ColumnList : SWQLNode
|
||
|
{
|
||
|
// Left Node is NULL
|
||
|
// Right Node is NULL
|
||
|
|
||
|
CFlexArray m_aColumnRefs ; // Pointers to SWQLColRef entries.
|
||
|
|
||
|
SWQLNode_ColumnList() { m_dwNodeType = TYPE_SWQLNode_ColumnList; }
|
||
|
~SWQLNode_ColumnList() { Empty(); }
|
||
|
void Empty();
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
struct SWQLColRef
|
||
|
{
|
||
|
LPWSTR m_pColName; // The column name or "*" or NULL
|
||
|
LPWSTR m_pTableRef; // The table/alias name or NULL if there is none
|
||
|
DWORD m_dwArrayIndex;
|
||
|
DWORD m_dwFlags; // WQL_FLAG_TABLE bit set if m_pTableRef
|
||
|
// is a table name
|
||
|
// WQL_FLAG_ALIAS bit set if m_pTableRef
|
||
|
// is a table alias
|
||
|
// WQL_FLAG_ASTERISK bit set if m_pColName is
|
||
|
// * (this is faster than to check than a
|
||
|
// string compare on <m_pColName> for "*".
|
||
|
// WQL_FLAG_NULL if the column name was "NULL"
|
||
|
// WQL_FLAG_FUNCTIONIZED is set if the column
|
||
|
// is wrapped in a function call.
|
||
|
// The function bits WQL_FLAG_UPPER or
|
||
|
// WQL_FLAG_LOWER will be set.
|
||
|
// WQL_FLAG_ARRAY_REF is set if the column
|
||
|
// is an array column, in which case
|
||
|
// m_dwArrayIndex is set to the array offset.
|
||
|
// WQL_FLAG_COMPLEX_NAME is set if the name
|
||
|
// is qualified in a deeply nested way,
|
||
|
// which requires examination of the <QName>
|
||
|
// object. In this case <m_pColName> is
|
||
|
// set to the last name, but m_pTableRef
|
||
|
// is left blank.
|
||
|
// WQL_FLAG_SORT_ASC to sort ascending (Order by only)
|
||
|
// WQL_FLAG_SORT_DESC to sort descending (Order by only)
|
||
|
|
||
|
SWQLQualifiedName *m_pQName; // The full qualified name
|
||
|
|
||
|
SWQLColRef() { m_pColName = NULL; m_pTableRef = 0;
|
||
|
m_dwFlags = 0; m_dwArrayIndex = 0; m_pQName = 0;
|
||
|
}
|
||
|
|
||
|
~SWQLColRef() { delete [] m_pColName; delete [] m_pTableRef; delete m_pQName; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_FromClause
|
||
|
//
|
||
|
// The subtree containing the tables selected from and any joins.
|
||
|
//
|
||
|
// SWQLNode_FromClause
|
||
|
// / \
|
||
|
// SWQLNode_TableRef NULL
|
||
|
// or SWQLNode_Join
|
||
|
// or SWQLNode_Sql89Join
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_FromClause (WQL_TOK_BASE + 4)
|
||
|
|
||
|
struct SWQLNode_FromClause : SWQLNode
|
||
|
{
|
||
|
// Left is SWQLNode_TableRef or SWQLNode_Join
|
||
|
// Right is NULL
|
||
|
|
||
|
SWQLNode_FromClause() { m_dwNodeType = TYPE_SWQLNode_FromClause; }
|
||
|
~SWQLNode_FromClause() {}
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_Sql89Join
|
||
|
//
|
||
|
// A subtree which expresses a SQL-89 join.
|
||
|
//
|
||
|
// SWQLNode_Sql89Join
|
||
|
// / \
|
||
|
// NULL NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_Sql89Join (WQL_TOK_BASE + 5)
|
||
|
|
||
|
struct SWQLNode_Sql89Join : SWQLNode
|
||
|
{
|
||
|
CFlexArray m_aValues; // Array of pointers to SWQLNode_TableRef
|
||
|
// objects
|
||
|
|
||
|
SWQLNode_Sql89Join() { m_dwNodeType = TYPE_SWQLNode_Sql89Join; }
|
||
|
~SWQLNode_Sql89Join() {Empty();};
|
||
|
void DebugDump();
|
||
|
void Empty();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_Join
|
||
|
//
|
||
|
// A subtree which expresses a join.
|
||
|
//
|
||
|
// SWQLNode_Join
|
||
|
// / \
|
||
|
// SWQLNode_JoinPair SWQLNode_OnClause or NULL.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_Join (WQL_TOK_BASE + 6)
|
||
|
|
||
|
struct SWQLNode_Join : SWQLNode
|
||
|
{
|
||
|
// Left ptr is SWQLNode_JoinPair
|
||
|
// Right ptr is ON clause. If NULL, there is no ON clause
|
||
|
// and the JOIN was a SQL-89 style join with the join condition
|
||
|
// present in the WHERE clause.
|
||
|
|
||
|
DWORD m_dwJoinType;
|
||
|
// One of WQL_FLAG_INNER_JOIN, WQL_FLAG_LEFT_OUTER_JOIN,
|
||
|
// WQL_FLAG_RIGHT_OUTER_JOIN or WQL_FLAG_FULL_OUTER_JOIN
|
||
|
DWORD m_dwFlags;
|
||
|
// Contains WQL_FLAG_FIRSTROW if used
|
||
|
|
||
|
SWQLNode_Join() { m_dwNodeType = TYPE_SWQLNode_Join; m_dwJoinType = m_dwFlags = 0; }
|
||
|
~SWQLNode_Join() {}
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_JoinPair
|
||
|
//
|
||
|
// SWQLNode_JoinPair
|
||
|
// / \
|
||
|
// <SWQLNode_Join or SWQLNode_TableRef>
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
#define TYPE_SWQLNode_JoinPair (WQL_TOK_BASE + 7)
|
||
|
|
||
|
struct SWQLNode_JoinPair : SWQLNode
|
||
|
{
|
||
|
// Left ptr is SWQLNode_Join or SWQLNode_TableRef
|
||
|
// Right ptr is SWQLNodeNode_Join or SWQL_NodeTableRef
|
||
|
|
||
|
SWQLNode_JoinPair() { m_dwNodeType = TYPE_SWQLNode_JoinPair; }
|
||
|
~SWQLNode_JoinPair() {}
|
||
|
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_TableRef
|
||
|
//
|
||
|
// A node representing a table name and its alias, if any.
|
||
|
//
|
||
|
// SWQLNode_TableRef
|
||
|
// / \
|
||
|
// NULL NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_TableRef (WQL_TOK_BASE + 8)
|
||
|
|
||
|
struct SWQLNode_TableRef : SWQLNode
|
||
|
{
|
||
|
LPWSTR m_pTableName; // The table
|
||
|
LPWSTR m_pAlias; // Table alias. NULL if not used.
|
||
|
|
||
|
SWQLNode_TableRef() { m_pTableName = 0; m_pAlias = 0; m_dwNodeType = TYPE_SWQLNode_TableRef; }
|
||
|
~SWQLNode_TableRef() { delete [] m_pTableName; delete [] m_pAlias; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_OnClause
|
||
|
//
|
||
|
// SWQLNode_OnClause
|
||
|
// / \
|
||
|
// <SWQLNode_RelExpr> NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
#define TYPE_SWQLNode_OnClause (WQL_TOK_BASE + 9)
|
||
|
|
||
|
struct SWQLNode_OnClause : SWQLNode
|
||
|
{
|
||
|
// Left ptr is <SWQLNode_RelExpr> which contains the ON clause.
|
||
|
// Right ptr is always NULL.
|
||
|
|
||
|
SWQLNode_OnClause() { m_dwNodeType = TYPE_SWQLNode_OnClause; }
|
||
|
~SWQLNode_OnClause() {}
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_WhereClause
|
||
|
//
|
||
|
// SWQLNode_WhereClause
|
||
|
// / \
|
||
|
// SWQLNode_RelExpr SWQLNode_WhereOptions or NULL
|
||
|
// or
|
||
|
// NULL if no conditions
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_WhereClause (WQL_TOK_BASE + 10)
|
||
|
|
||
|
struct SWQLNode_WhereClause : SWQLNode
|
||
|
{
|
||
|
// Left ptr is SWQLNode_RelExpr.
|
||
|
// Right ptr is SQLNode_QueryOptions or NULL if none
|
||
|
|
||
|
SWQLNode_WhereClause() { m_dwNodeType = TYPE_SWQLNode_WhereClause; }
|
||
|
~SWQLNode_WhereClause() {}
|
||
|
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// struct SWQLTypedExpr
|
||
|
//
|
||
|
// This represents a typed subexpression in a where clause:
|
||
|
//
|
||
|
// mycol < 2
|
||
|
// 33 <= tbl1.col2
|
||
|
// tbl3.col4 = tbl4.col5
|
||
|
// ...etc.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
struct SWQLTypedExpr
|
||
|
{
|
||
|
LPWSTR m_pTableRef; // For qualified column names,
|
||
|
// NULL if not used
|
||
|
LPWSTR m_pColRef; // Column name
|
||
|
|
||
|
DWORD m_dwRelOperator; // The operator used: WQL_TOK_LE,
|
||
|
// WQL_TOK_GE, WQL_TOK_LIKE etc.
|
||
|
// WQL_TOK_IN_CONST_LIST
|
||
|
// WQL_TOK_NOT_IN_CONST_LIST
|
||
|
// WQL_TOK_IN_SUBSELECT
|
||
|
// WQL_TOK_NOT_IN_SUBSELECT
|
||
|
|
||
|
SWQLTypedConst *m_pConstValue; // A const value
|
||
|
SWQLTypedConst *m_pConstValue2; // The other const value used with BETWEEN
|
||
|
|
||
|
LPWSTR m_pJoinTableRef; // The joined table name or its alias,
|
||
|
// NULL if not used
|
||
|
LPWSTR m_pJoinColRef; // The joined column name
|
||
|
|
||
|
LPWSTR m_pIntrinsicFuncOnColRef;
|
||
|
LPWSTR m_pIntrinsicFuncOnJoinColRef;
|
||
|
LPWSTR m_pIntrinsicFuncOnConstValue;
|
||
|
|
||
|
SWQLNode *m_pLeftFunction; // More detail for DATEPART, etc.
|
||
|
SWQLNode *m_pRightFunction; // More detail for DATEPART, etc.
|
||
|
|
||
|
DWORD m_dwLeftArrayIndex;
|
||
|
DWORD m_dwRightArrayIndex;
|
||
|
|
||
|
SWQLQualifiedName *m_pQNRight;
|
||
|
SWQLQualifiedName *m_pQNLeft;
|
||
|
|
||
|
DWORD m_dwLeftFlags;
|
||
|
DWORD m_dwRightFlags;
|
||
|
// Each of the above to Flags shows the expression layout on each side
|
||
|
// of the operator.
|
||
|
// WQL_FLAG_CONST = A typed constant was used
|
||
|
// WQL_FLAG_COLUMN = Column field was used
|
||
|
// WQL_FLAG_TABLE = Table/Alias was used
|
||
|
// WQL_FLAG_COMPLEX = Complex qualified name and/or array was used
|
||
|
// WQL_FLAG_FUNCTIONIZED = Function was applied over the const or col.
|
||
|
|
||
|
|
||
|
// For IN and NOT IN clauses.
|
||
|
// ==========================
|
||
|
|
||
|
SWQLNode *m_pSubSelect;
|
||
|
|
||
|
SWQLConstList *m_pConstList; // For IN clause with constant-list
|
||
|
|
||
|
/*
|
||
|
(1) If a const is tested against a column, then <m_pConstValue> will
|
||
|
be used to represent it, and the table+col referenced will be in
|
||
|
<m_pTableRef> and <m_pColRef>.
|
||
|
|
||
|
(2) If a join occurs, then <m_pConstValue> will be NULL.
|
||
|
|
||
|
(3) Intrinsic functions (primarily UPPER() and LOWER()) can be applied
|
||
|
to the column references or the constant. The function names will
|
||
|
be placed in the <m_pIntrinsic...> pointers when applied.
|
||
|
|
||
|
(4) If <m_dwRelOperator> is WQL_TOK_IN_CONST_LIST or WQL_TOK_NOT_IN_CONST_LIST
|
||
|
then <m_aConstSet> is an array of pointers to SWQLTypedConst structs representing
|
||
|
the set of constants that the referenced column must intersect with.
|
||
|
|
||
|
(5) If <m_dwRelOperator> is WQL_TOK_IN_SUBSELECT or WQL_TOK_NOT_IN_SUBSELECT
|
||
|
then m_pSubSelect is a pointer to an embedded subselect tree in the form
|
||
|
of a SWQLNode_Select struct, beginning the root of an entirely new select
|
||
|
statement.
|
||
|
*/
|
||
|
|
||
|
SWQLTypedExpr();
|
||
|
~SWQLTypedExpr() { Empty(); }
|
||
|
void DebugDump();
|
||
|
void Empty();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_RelExpr
|
||
|
//
|
||
|
// SWQLNode_RelExpr
|
||
|
// / \
|
||
|
// SWQLNode_RelExpr SWQLNode_RelExpr
|
||
|
// or NULL or NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_RelExpr (WQL_TOK_BASE + 11)
|
||
|
|
||
|
struct SWQLNode_RelExpr : SWQLNode
|
||
|
{
|
||
|
DWORD m_dwExprType; // WQL_TOK_OR
|
||
|
// WQL_TOK_AND
|
||
|
// WQL_TOK_NOT
|
||
|
// WQL_TOK_TYPED_EXPR
|
||
|
|
||
|
SWQLTypedExpr *m_pTypedExpr;
|
||
|
|
||
|
/*
|
||
|
(1) If the <m_dwExprType> is WQL_TOK_AND or WQL_TOK_OR, then each of
|
||
|
the two subnodes are themselves SWQLNode_RelExpr nodes and
|
||
|
<m_pTypedExpr> points to NULL.
|
||
|
|
||
|
(2) If <m_dwExprType> is WQL_TOK_NOT, then <m_pLeft> points to a
|
||
|
SWQLNode_RelExpr containing the subclause to which to apply the NOT
|
||
|
operation and <m_pRight> points to NULL.
|
||
|
|
||
|
(3) If <m_dwExprType> is WQL_TOK_TYPED_EXPR, then <m_pLeft> and
|
||
|
<m_pRight> both point to NULL, and <m_pTypedExpr> contains a typed
|
||
|
relational subexpression.
|
||
|
|
||
|
(4) Parentheses have been removed and are implied by the nesting.
|
||
|
*/
|
||
|
|
||
|
SWQLNode_RelExpr() { m_dwNodeType = TYPE_SWQLNode_RelExpr; m_pTypedExpr = 0; m_dwExprType = 0; }
|
||
|
~SWQLNode_RelExpr() { delete m_pTypedExpr; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_WhereOptions
|
||
|
//
|
||
|
// SWQLNode_WhereOptions
|
||
|
// / \
|
||
|
// SWQLNode_GroupBy SWQLNode_OrderBy
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_WhereOptions (WQL_TOK_BASE + 12)
|
||
|
|
||
|
struct SWQLNode_WhereOptions : SWQLNode
|
||
|
{
|
||
|
// left ptr is SWQLNode_GroupBy, or NULL if not used
|
||
|
// right ptr is SWQLNode_OrderBy, or NULL if not used
|
||
|
|
||
|
SWQLNode_WhereOptions() { m_dwNodeType = TYPE_SWQLNode_WhereOptions; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_GroupBy
|
||
|
//
|
||
|
// SWQLNode_GroupBy
|
||
|
// / \
|
||
|
// SWQLNode_ColumnList SWQLNode_Having
|
||
|
// or NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_GroupBy (WQL_TOK_BASE + 13)
|
||
|
|
||
|
struct SWQLNode_GroupBy : SWQLNode
|
||
|
{
|
||
|
// left ptr is SWQLNode_ColumnList of columns to group by
|
||
|
// right ptr is Having clause, if any
|
||
|
|
||
|
SWQLNode_GroupBy() { m_dwNodeType = TYPE_SWQLNode_GroupBy; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_Having
|
||
|
//
|
||
|
// SWQLNode_Having
|
||
|
// / \
|
||
|
// SWQLNode_RelExpr NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_Having (WQL_TOK_BASE + 14)
|
||
|
|
||
|
struct SWQLNode_Having : SWQLNode
|
||
|
{
|
||
|
// left ptr is SQLNode_RelExpr pointing to HAVING expressions
|
||
|
// right ptr is NULL
|
||
|
|
||
|
SWQLNode_Having() { m_dwNodeType = TYPE_SWQLNode_Having; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_OrderBy
|
||
|
//
|
||
|
// SWQLNode_OrderBy
|
||
|
// / \
|
||
|
// SWQLNode_ColumnList NULL
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#define TYPE_SWQLNode_OrderBy (WQL_TOK_BASE + 15)
|
||
|
|
||
|
struct SWQLNode_OrderBy : SWQLNode
|
||
|
{
|
||
|
// left ptr is SWQLNode_ColumnList
|
||
|
// right ptr is NULL
|
||
|
SWQLNode_OrderBy() { m_dwNodeType = TYPE_SWQLNode_OrderBy; }
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SWQLNode_Datepart
|
||
|
//
|
||
|
// Contains a datepart call.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
#define TYPE_SWQLNode_Datepart (WQL_TOK_BASE + 16)
|
||
|
|
||
|
struct SWQLNode_Datepart : SWQLNode
|
||
|
{
|
||
|
int m_nDatepart; // One of WQL_TOK_YEAR, WQL_TOK_MONTH,
|
||
|
// WQL_TOK_DAY, WQL_TOK_HOUR, WQL_TOK_MINUTE
|
||
|
// WQL_TOK_SECOND
|
||
|
|
||
|
SWQLColRef *m_pColRef; // The column to which DATEPART applies
|
||
|
|
||
|
SWQLNode_Datepart() { m_dwNodeType = TYPE_SWQLNode_Datepart; m_nDatepart = 0; }
|
||
|
~SWQLNode_Datepart() { delete m_pColRef; }
|
||
|
|
||
|
void DebugDump();
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif
|