Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

813 lines
34 KiB

/***************************************************************************/
/* PARSE.H */
/* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */
/***************************************************************************/
#define SQLNODEIDX int
#define NO_SQLNODE (-1)
#define ROOT_SQLNODE 0
#define SQLNODE_ALLOC 16
#define STRINGIDX int
#define NO_STRING (-1)
#define STRING_ALLOC 512 //was 128
#define NO_SCALE (-1)
#define OP_NONE 0
#define OP_EQ 1
#define OP_NE 2
#define OP_LE 3
#define OP_LT 4
#define OP_GE 5
#define OP_GT 6
#define OP_IN 7
#define OP_NOTIN 8
#define OP_LIKE 9
#define OP_NOTLIKE 10
#define OP_NEG 11
#define OP_PLUS 12
#define OP_MINUS 13
#define OP_TIMES 14
#define OP_DIVIDEDBY 15
#define OP_NOT 16
#define OP_AND 17
#define OP_OR 18
#define OP_EXISTS 19
#define AGG_AVG 1
#define AGG_COUNT 2
#define AGG_MAX 3
#define AGG_MIN 4
#define AGG_SUM 5
#define SELECT_NOTSELECT 0
#define SELECT_ALL 1
#define SELECT_ANY 2
#define SELECT_ONE 3
#define SELECT_EXISTS 4
#define NOT_IN_SORT_RECORD 0
typedef struct tagSQLNODE { /* Node in SQL parse tree */
UWORD sqlNodeType; /* NODE_TYPE_* */
SWORD sqlDataType; /* TYPE_* (set by SemanticCheck()) */
SWORD sqlSqlType; /* SQL_* (set by SemanticCheck()) */
SDWORD sqlPrecision; /* Precision (set by SemanticCheck()) */
SWORD sqlScale; /* Scale if sqlSqlType is */
/* SQL_DECIMAL or SQL_NUMERIC */
/* (set by SemanticCheck()) */
BOOL sqlIsNull; /* Is expression value NULL (set */
/* at execution time)? */
union {
double Double; /* When sqlDataType == TYPE_DOUBLE or */
/* TYPE_INTEGER */
LPUSTR String; /* When sqlDataType == TYPE_CHAR or */
/* TYPE_NUMERIC */
DATE_STRUCT Date; /* When sqlDataType == TYPE_DATE */
TIME_STRUCT Time; /* When sqlDataType == TYPE_TIME */
TIMESTAMP_STRUCT Timestamp; /* When sqlDataType == TYPE_TIMESTAMP */
LPUSTR Binary; /* When sqlDataType == TYPE_BINARY */
/* (length is in first four bytes) */
} value;
union {
/* NODE_TYPE_ROOT */
struct {
LPISAM lpISAM; /* ISAM opening */
HGLOBAL hParseArray; /* Handle to memory holding this */
/* parse node array */
int cParseArray; /* Number of elements in */
/* hParseArray */
int iParseArray; /* Last element in hParseArray */
/* in use */
HGLOBAL hStringArea; /* Handle to memory holding the */
/* string area */
LPUSTR lpStringArea; /* Pointer to memory holding the */
/* string area */
int cbStringArea; /* Size of string area */
int ibStringArea; /* Last byte in string area in */
/* use */
SQLNODEIDX sql; /* CREATE, DROP, SELECT, INSERT, */
/* DELETE, UPDATE, */
/* CREATEINDEX, DROPINDEX, */
/* PASSTHROUGH */
SQLNODEIDX parameters; /* List of parameters for the */
/* query (this points to a */
/* PARAMETER or NO_SQLNODE) */
BOOL passthroughParams; /* Are parameters from a */
/* passthrough statement? */
} root;
/* NODE_TYPE_CREATE */
struct {
STRINGIDX Table; /* Offset into the string area */
/* for the name of the table */
SQLNODEIDX Columns; /* CREATECOLS */
} create;
/* NODE_TYPE_DROP */
struct {
STRINGIDX Table; /* Offset into the string area */
/* for the name of the table */
} drop;
/* NODE_TYPE_CREATEINDEX */
struct {
STRINGIDX Index; /* Offset into the string area */
/* for the name of the table */
SQLNODEIDX Table; /* TABLE */
SQLNODEIDX Columns; /* SORTCOLUMNS */
BOOL Unique; /* Unique index? */
} createindex;
/* NODE_TYPE_DROPINDEX */
struct {
STRINGIDX Index; /* Offset into the string area */
/* for the name of the index */
} dropindex;
/* NODE_TYPE_SELECT */
struct {
BOOL Distinct; /* TRUE, FALSE */
SQLNODEIDX Values; /* VALUES */
SQLNODEIDX Tables; /* TABLES */
SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */
/* NO_SQLNODE */
SQLNODEIDX Groupbycolumns; /* GROUPBYCOLUMNS, NO_SQLNODE */
SQLNODEIDX Having; /* BOOLEAN, COMPARISON, */
/* NO_SQLNODE */
SQLNODEIDX Sortcolumns; /* SORTCOLUMNS, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */
STRINGIDX SortDirective; /* Offset into the string area */
/* to sort directive */
UDWORD SortRecordsize; /* Size of records in sort file */
UDWORD SortBookmarks; /* Offset of bookmarks in sort */
/* record (one based) */
SQLNODEIDX Aggregates; /* List of aggregates for the */
/* query (this points to a */
/* AGGREGATE or NO_SQLNODE) */
UDWORD SortKeysize; /* Size of key in sort file */
STRINGIDX DistinctDirective; /* Offset into the string area */
/* to DISTINCT sort directive */
UDWORD DistinctRecordsize; /* Size of records in DISTINCT */
/* sort file */
BOOL ImplicitGroupby; /* If TRUE, the user did not */
/* specify a groupby but one */
/* that contains the entire */
/* table was added because */
/* select list specified had */
/* an aggregate function */
SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
/* UPDATE, NO_SQLNODE */
/* The following elements are set by Optimize(): */
BOOL fPushdownSort; /* Use ISAMSort() routines? */
BOOL fMSAccess; /* Is this the funny MSAccess */
/* query (see OPTIMIZE.C) ? */
/* The following elements are set by ExecuteQuery(): */
SDWORD RowCount; /* Number of rows */
SDWORD CurrentRow; /* Current row fetched */
STRINGIDX SortfileName; /* Name of the sortfile */
HFILE Sortfile; /* Sortfile */
BOOL ReturningDistinct; /* Does the sort file contain */
/* results of a DISTINCT op */
} select;
/* NODE_TYPE_INSERT */
struct {
SQLNODEIDX Table; /* TABLE */
SQLNODEIDX Columns; /* COLUMNS */
SQLNODEIDX Values; /* VALUES, SELECT */
} insert;
/* NODE_TYPE_DELETE */
struct {
SQLNODEIDX Table; /* TABLE */
SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */
/* NO_SQLNODE */
} delet;
/* NODE_TYPE_UPDATE */
struct {
SQLNODEIDX Table; /* TABLE */
SQLNODEIDX Updatevalues; /* UPDATEVALUES */
SQLNODEIDX Predicate; /* BOOLEAN, COMPARISON, */
/* NO_SQLNODE */
} update;
/* NODE_TYPE_PASSTHROUGH */
/* NODE_TYPE_TABLES */
struct {
SQLNODEIDX Table; /* TABLE */
SQLNODEIDX Next; /* TABLES, NO_SQLNODE */
} tables;
/* NODE_TYPE_VALUES */
struct {
SQLNODEIDX Value; /* COLUMN, ALGEBRAIC, SCALAR, */
/* AGGREGATE, NUMERIC, */
/* STRING, PARAMETER, USER, */
/* NULL */
STRINGIDX Alias; /* Offset into the string area */
/* for the alias (only used */
/* for SELECT statements) */
SQLNODEIDX Next; /* VALUES, NO_SQLNODE */
} values;
/* NODE_TYPE_COLUMNS */
struct {
SQLNODEIDX Column; /* COLUMN */
SQLNODEIDX Next; /* COLUMNS, NO_SQLNODE */
} columns;
/* NODE_TYPE_SORTCOLUMNS */
struct {
SQLNODEIDX Column; /* COLUMN */
BOOL Descending; /* TRUE, FALSE */
SQLNODEIDX Next; /* SORTCOLUMNS, NO_SQLNODE */
} sortcolumns;
/* NODE_TYPE_GROUPBYCOLUMNS */
struct {
SQLNODEIDX Column; /* COLUMN */
SQLNODEIDX Next; /* GROUPBYCOLUMNS, NO_SQLNODE */
} groupbycolumns;
/* NODE_TYPE_UPDATEVALUES */
struct {
SQLNODEIDX Column; /* COLUMN */
SQLNODEIDX Value; /* COLUMN, ALGEBRAIC, SCALAR, */
/* AGGREGATE, NUMERIC, */
/* STRING, PARAMETER, USER, */
/* NULL */
SQLNODEIDX Next; /* UPDATEVALUES, NO_SQLNODE */
} updatevalues;
/* NODE_TYPE_CREATECOLS */
struct {
STRINGIDX Name; /* Offset into the string area */
/* for the name of the column */
STRINGIDX Type; /* Offset into the string area */
/* for the data type name */
UWORD Params; /* Number of create params */
UDWORD Param1; /* Value of param 1 (if any) */
UDWORD Param2; /* Value of param 2 (if any) */
SQLNODEIDX Next; /* CREATECOLS, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */
UWORD iSqlType; /* Index into SQLTypes[] of */
/* the type of the column */
} createcols;
/* NODE_TYPE_BOOLEAN */
struct {
UWORD Operator; /* OP_NOT, OP_AND, or OP_OR */
SQLNODEIDX Left; /* BOOLEAN, COMPARISON, */
SQLNODEIDX Right; /* BOOLEAN, COMPARISON, */
/* NO_SQLNODE */
} boolean;
/* NODE_TYPE_COMPARISON */
struct {
UWORD Operator; /* OP_EQ, OP_NE, OP_LE, OP_LT, */
/* OP_GE, OP_GT, OP_LIKE, */
/* OP_NOTLIKE, OP_IN, */
/* OP_NOTIN, OP_EXISTS */
UWORD SelectModifier; /* SELECT_NOTSELECT, */
/* SELECT_ALL, SELECT_ANY, */
/* SELECT_ONE, SELECT_EXISTS */
SQLNODEIDX Left; /* COLUMN, ALGEBRAIC, SCALAR, */
/* AGGREGATE, NUMERIC, */
/* STRING, PARAMETER, USER, */
/* SELECT, NULL */
SQLNODEIDX Right; /* COLUMN, ALGEBRAIC, SCALAR, */
/* AGGREGATE, NUMERIC, */
/* STRING, PARAMETER, USER, */
/* VALUES (for IN/NOTIN op), */
/* SELECT, NULL */
/* The following elements are set by Optimize(): */
UWORD fSelectivity; /* Selectivity the restriction */
SQLNODEIDX NextRestrict; /* COMPARISON, NO_SQLNODE */
/* The next restriction on the */
/* list of restrictions */
} comparison;
/* NODE_TYPE_ALGEBRAIC */
struct {
UWORD Operator; /* OP_NEG, OP_PLUS, */
/* OP_MINUS, OP_TIMES, */
/* OP_DIVIDEDBY */
SQLNODEIDX Left; /* COLUMN, ALGEBRAIC, SCALAR, */
/* AGGREGATE, NUMERIC, */
/* STRING, PARAMETER, USER, */
/* NULL */
SQLNODEIDX Right; /* COLUMN, ALGEBRAIC, SCALAR, */
/* AGGREGATE, NUMERIC, */
/* STRING, PARAMETER, USER, */
/* NULL, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */
STRINGIDX Value; /* Value used to evaluate */
/* expressions */
STRINGIDX WorkBuffer1; /* Workbuffer used to evaluate */
/* NUMERIC multiply & divide */
STRINGIDX WorkBuffer2; /* Workbuffer used to evaluate */
/* NUMERIC divide */
STRINGIDX WorkBuffer3; /* Workbuffer used to evaluate */
/* NUMERIC divide */
UDWORD DistinctOffset; /* The offset the column is in */
/* in the sort DISTINCT */
/* record (one based). */
UDWORD DistinctLength; /* The length of the column in */
/* the sort DISTINCT record. */
SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
/* UPDATE */
} algebraic;
/* NODE_TYPE_SCALAR */
struct {
STRINGIDX Function; /* Name of the function */
SQLNODEIDX Arguments; /* VALUES, NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */
UWORD Id; /* Scaler function id */
UWORD Interval; /* Interval for TIMESTAMPADD */
/* and TIMESTAMPDIFF */
STRINGIDX Value; /* Value used to evaluate */
/* expressions */
UDWORD DistinctOffset; /* The offset the column is in */
/* in the sort DISTINCT */
/* record (one based). */
UDWORD DistinctLength; /* The length of the column in */
/* the sort DISTINCT record. */
SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
/* UPDATE */
} scalar;
/* NODE_TYPE_AGGREGATE */
struct {
UWORD Operator; /* AGG_AVE, AGG_COUNT, */
/* AGG_MAX, AGG_MIN, AGG_SUM */
SQLNODEIDX Expression; /* COLUMN, ALGEBRAIC, SCALAR, */
/* AGGREGATE, NUMERIC, */
/* STRING, PARAMETER, USER, */
/* NULL */
/* The following elements are set by SemanticCheck(): */
STRINGIDX Value; /* Column value used to */
/* evaluate expressions */
UDWORD Offset; /* The offset the column is in */
/* in the sort record (one */
/* based). */
UDWORD Length; /* The length of the column in */
/* the sort record. */
UDWORD DistinctOffset; /* The offset the column is in */
/* in the sort DISTINCT */
/* record (one based). */
UDWORD DistinctLength; /* The length of the column in */
/* the sort DISTINCT record. */
SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
/* UPDATE */
SQLNODEIDX Next; /* Rest of list of AGG */
/* functions for the query */
/* (this points to an */
/* AGGREGATE or NO_SQLNODE) */
/* The following elements are set at execution time: */
double Count; /* Number of records that had */
/* a non-NULL value */
} aggregate;
/* NODE_TYPE_TABLE */
struct {
STRINGIDX Name; /* Offset into the string area */
/* for the name of the table */
STRINGIDX Qualifier; /* Offset into the string area */
/* for the qulaifier of the table */
STRINGIDX Alias; /* Offset into the string area */
/* for the name of the alias */
SQLNODEIDX OuterJoinFromTables;/* TABLES, NO_SQLNODE */
SQLNODEIDX OuterJoinPredicate; /* BOOLEAN, COMPARISON, */
/* NO_SQLNODE */
/* The following elements are set by SemanticCheck(): */
LPISAMTABLEDEF Handle; /* Table handle */
/* The following elements are set by Optimize(): */
UWORD cRestrict; /* The number of Restrict nodes */
SQLNODEIDX Restrict; /* COMPARISON, NO_SQLNODE (if */
/* this points to a comparison */
/* node, the node is somewhere */
/* in the predicate, and is in */
/* the form: */
/* */
/* <column> <op> <constant> */
/* */
/* where <column> is some */
/* column of this table) */
UWORD Sortsequence; /* The relative position of */
/* this table when sorting */
UWORD Sortcount; /* The number of sort columns */
/* for this table */
SQLNODEIDX Sortcolumns; /* SORTCOLUMNS, NO_SQLNODE (the */
/* first in the list of sort */
/* columns for this table) */
/* The following elements are set at execution time: */
BOOL AllNull; /* Use NULL as value for all */
/* columns in current row */
BOOL Rewound; /* Is table positioned before */
/* first record? */
} table;
/* NODE_TYPE_COLUMN */
struct {
STRINGIDX Tablealias; /* Offset into the string area */
/* for the name of the alias */
STRINGIDX Column; /* Offset into the string area */
/* for the name of the column */
STRINGIDX Qualifier; /* Offset into the string area */
/* for the name of the */
/* qualifier */
BOOL MatchedAlias; /* indicates if the TableAlias */
/* refers to a table name or an*/
/* alias. */
SQLNODEIDX TableIndex; /* index of table node to which*/
/* column belongs */
/* This renders the info above */
/* redundant. */
/* The following elements are set by SemanticCheck(): */
SQLNODEIDX Table; /* TABLE, NO_SQLNODE. Table */
/* of the column. If */
/* NO_SQLNODE, the column is */
/* in sort record. */
SWORD Id; /* Ordinal position of column */
STRINGIDX Value; /* Column value used to */
/* evaluate expressions */
BOOL InSortRecord; /* Is this column in the sort */
/* record? */
UDWORD Offset; /* The offset the column is in */
/* in the sort record (one */
/* based). */
UDWORD Length; /* The length of the column if */
/* it is in the sort record. */
UDWORD DistinctOffset; /* The offset the column is in */
/* in the sort DISTINCT */
/* record (one based). */
UDWORD DistinctLength; /* The length of the column in */
/* the sort DISTINCT record. */
SQLNODEIDX EnclosingStatement; /* SELECT, INSERT, DELETE, */
/* UPDATE */
} column;
/* NODE_TYPE_STRING */
struct {
STRINGIDX Value; /* Offset into the string area */
/* for the string */
} string;
/* NODE_TYPE_NUMERIC */
struct {
double Value;
STRINGIDX Numeric;
} numeric;
/* NODE_TYPE_PARAMETER */
struct {
UWORD Id; /* Ordinal position of parameter */
SQLNODEIDX Next; /* Rest of list of parameters for */
/* the query (this points to a */
/* PARAMETER or NO_SQLNODE) */
/* The following elements are set by SemanticCheck(): */
STRINGIDX Value; /* Parameter value used to */
/* evaluate expressions */
/* The following elements are set at execution time: */
BOOL AtExec; /* Value to be provided by */
/* ParamData()/PutData() */
} parameter;
/* NODE_TYPE_USER */
/* NODE_TYPE_NULL */
/* NODE_TYPE_DATE */
struct {
DATE_STRUCT Value;
} date;
/* NODE_TYPE_TIME */
struct {
TIME_STRUCT Value;
} time;
/* NODE_TYPE_TIMESTAMP */
struct {
TIMESTAMP_STRUCT Value;
} timestamp;
} node;
} SQLNODE,
FAR * LPSQLNODE;
#define LPSQLTREE LPSQLNODE
#define NODE_TYPE_NONE 0
#define NODE_TYPE_ROOT 1
#define NODE_TYPE_CREATE 2
#define NODE_TYPE_DROP 3
#define NODE_TYPE_SELECT 4
#define NODE_TYPE_INSERT 5
#define NODE_TYPE_DELETE 6
#define NODE_TYPE_UPDATE 7
#define NODE_TYPE_PASSTHROUGH 8
#define NODE_TYPE_TABLES 9
#define NODE_TYPE_VALUES 10
#define NODE_TYPE_COLUMNS 11
#define NODE_TYPE_SORTCOLUMNS 12
#define NODE_TYPE_GROUPBYCOLUMNS 13
#define NODE_TYPE_UPDATEVALUES 14
#define NODE_TYPE_CREATECOLS 15
#define NODE_TYPE_BOOLEAN 16
#define NODE_TYPE_COMPARISON 17
#define NODE_TYPE_ALGEBRAIC 18
#define NODE_TYPE_AGGREGATE 19
#define NODE_TYPE_TABLE 20
#define NODE_TYPE_COLUMN 21
#define NODE_TYPE_STRING 22
#define NODE_TYPE_NUMERIC 23
#define NODE_TYPE_PARAMETER 24
#define NODE_TYPE_USER 25
#define NODE_TYPE_NULL 26
#define NODE_TYPE_DATE 27
#define NODE_TYPE_TIME 28
#define NODE_TYPE_TIMESTAMP 29
#define NODE_TYPE_CREATEINDEX 30
#define NODE_TYPE_DROPINDEX 31
#define NODE_TYPE_SCALAR 32
//Class used to re-convert WHERE predicate back into character string
class PredicateParser
{
private:
LPSQLTREE FAR *lplpSql;
LPISAMTABLEDEF lpISAMTableDef;
BOOL fError;
BOOL fSupportLIKEs;
//Generates string for a comparision expression
void GenerateComparisonString(char* lpLeftString, char* lpRightString, UWORD wOperator, UWORD wSelectModifier, char** lpOutputStr);
//Generates string for a boolean expression
void GenerateBooleanString(char* lpLeftString, char* lpRightString, UWORD wOperator, char** lpOutputStr);
//Generates string for an aggregate expression
void GenerateAggregateString(char* lpLeftString, UWORD wOperator, char** lpOutputStr);
//Generates string for an algebraic expression
void GenerateAlgebraicString(char* lpLeftString, char* lpRightString, UWORD wOperator, char** lpOutputStr);
//Builds a column reference
void GenerateColumnRef(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
public:
//Generates WHERE predicate string from SQLNODETREE
void GeneratePredicateString(LPSQLNODE lpSqlNode, char** lpOutputStr, BOOL fIsSQL89 = TRUE);
//Builds GROUP BY statement
void GenerateGroupByString(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
//Builds ORDER BY statement
void GenerateOrderByString(LPSQLNODE lpSqlNode, char ** lpOutputStr, BOOL fIsSQL89);
// PredicateParser(LPSQLTREE FAR *lplpTheSql, SQLNODEIDX iPredicate)
// {lplpSql = lplpTheSql; Predicate = iPredicate;}
PredicateParser(LPSQLTREE FAR *lplpTheSql, LPISAMTABLEDEF lpISAMTblDef, BOOL fLIKEs = TRUE)
{lplpSql = lplpTheSql; lpISAMTableDef = lpISAMTblDef; fError = FALSE; fSupportLIKEs = fLIKEs;}
~PredicateParser() {;}
};
class PassthroughLookupTable
{
private:
char tableAlias [MAX_QUALIFIER_NAME_LENGTH + 1];
char columnName [MAX_COLUMN_NAME_LENGTH + 1];
public:
BOOL SetTableAlias(char* tblAlias);
char* GetTableAlias() {return tableAlias;}
BOOL SetColumnName(char* columName);
char* GetColumnName() {return columnName;}
PassthroughLookupTable();
};
void TidyupPassthroughMap(CMapWordToPtr* passthroughMap);
class VirtualInstanceInfo
{
public:
//each element in the CMapStringToPtr is keyed on
//TableAlias.ColumnName
long cElements; //number of elements in this array
long cCycle; //value change cycle for instances
VirtualInstanceInfo();
~VirtualInstanceInfo();
};
class VirtualInstanceManager
{
private:
CMapStringToPtr* virtualInfo;
char* ConstructKey(LPCTSTR TableAlias, LPCTSTR ColumnName);
IWbemClassObject* GetWbemObject(CBString& myTableAlias, IWbemClassObject* myInstance);
public:
long currentInstance; //zero-based index
long cNumberOfInstances;
void AddColumnInstance(LPCTSTR TableAlias, LPCTSTR ColumnName, VirtualInstanceInfo* col);
long GetArrayIndex(LPCTSTR TableAlias, LPCTSTR ColumnName, long instanceNum);
// void Testy();
void Load(CMapWordToPtr* passthroughMap, IWbemClassObject* myInstance);
BOOL GetVariantValue(CBString& myTableAlias, CBString& myColumnName, IWbemClassObject* myInstance, VARIANT FAR* myVal);
VirtualInstanceManager();
~VirtualInstanceManager();
};
class TableColumnList
{
public:
SQLNODEIDX idxColumnName; //column info
SQLNODEIDX idxTableAlias; //table alias for column
LPISAMTABLEDEF lpISAMTableDef; //table info
TableColumnList* Next; //Next item in list
TableColumnList(SQLNODEIDX idx, SQLNODEIDX idxAlias, LPISAMTABLEDEF lpTableDef)
{idxColumnName = idx; idxTableAlias = idxAlias; lpISAMTableDef = lpTableDef; Next = NULL;}
~TableColumnList() {delete Next;}
};
#define WQL_SINGLE_TABLE 1
#define WQL_MULTI_TABLE 2
class TableColumnInfo
{
private:
LPSQLTREE FAR *lplpSql;
LPSQLTREE FAR * lplpSqlNode;
BOOL fIsValid;
ULONG theMode;
STRINGIDX idxTableQualifer;
BOOL fDistinct;
BOOL fHasScalarFunction;
BOOL fIsSelectStar;
BOOL m_aggregateExists;
void Analize(LPSQLNODE lpNode);
void StringConcat(char** resultString, char* myStr);
// void AddJoin(_bstr_t & tableList, SQLNODEIDX joinidx);
void AddJoinPredicate(char** tableList, SQLNODEIDX predicateidx);
public:
TableColumnList* lpList;
void BuildTableList(char** tableList, BOOL &fIsSQL89, SQLNODEIDX idx = NO_SQLNODE);
//Check if there is zero or one column/table entires in list
//This is used to check for COUNT(*)
BOOL IsZeroOrOneList();
//Have any aggregate functions been detected
BOOL HasAggregateFunctions() {return m_aggregateExists;}
//Is SELECT DISTINCT select-list FROM .....
BOOL IsDistinct() {return fDistinct;}
//Is SELECT * FROM ...
BOOL IsSelectStar() {return fIsSelectStar;}
//Was table column info parsed successfully
BOOL IsValid() {return fIsValid;}
//Indicate if query contains scalar function
BOOL HasScalarFunction() {return fHasScalarFunction;}
//Builds a select list for the chosen table
void BuildSelectList(LPISAMTABLEDEF lpTableDef, char** lpSelectListStr, BOOL fIsSQL89 = TRUE, CMapWordToPtr** ppPassthroughMap = NULL);
//Builds whole WQL statement
void BuildFullWQL(char** lpWQLStr, CMapWordToPtr** ppPassthroughMap = NULL);
STRINGIDX GetTableQualifier() {return idxTableQualifer;}
//Indicates if at least one column in the specified table
//is refernced in the SQL statement
BOOL IsTableReferenced(LPISAMTABLEDEF lpTableDef);
TableColumnInfo(LPSQLTREE FAR *lplpTheSql, LPSQLTREE FAR * lpSqlN, ULONG mode = WQL_SINGLE_TABLE);
~TableColumnInfo() {delete lpList;}
};
#define DATETIME_FORMAT_LEN 21
#define DATETIME_DATE_LEN 8
#define DATETIME_TIME_LEN 6
#define DATETIME_YEAR_LEN 4
#define DATETIME_MONTH_LEN 2
#define DATETIME_DAY_LEN 2
#define DATETIME_HOUR_LEN 2
#define DATETIME_MIN_LEN 2
#define DATETIME_SEC_LEN 2
#define DATETIME_MICROSEC_LEN 6
class DateTimeParser
{
private:
BOOL fIsValid;
BOOL fValidDate;
BOOL fValidTime;
BOOL fIsaTimestamp;
BOOL fIsaDate;
BOOL fIsaTime;
ULONG m_year;
ULONG m_month;
ULONG m_day;
ULONG m_hour;
ULONG m_min;
ULONG m_sec;
ULONG m_microSec;
char dateTimeBuff[DATETIME_FORMAT_LEN + 1];
char tempBuff[DATETIME_MICROSEC_LEN + 1];
BOOL IsNumber(char bChar);
void FetchField(char* lpStr, WORD wFieldLen, ULONG &wValue);
void ValidateFields();
public:
BOOL IsValid() {return fIsValid;}
BOOL IsTimestamp() {return fIsaTimestamp;}
BOOL IsDate() {return fIsaDate;}
BOOL IsTime() {return fIsaTime;}
ULONG GetYear() {return m_year;}
ULONG GetMonth() {return m_month;}
ULONG GetDay() {return m_day;}
ULONG GetHour() {return m_hour;}
ULONG GetMin() {return m_min;}
ULONG GetSec() {return m_sec;}
ULONG GetMicroSec() {return m_microSec;}
DateTimeParser(BSTR dateTimeStr);
~DateTimeParser() {;}
};
/***************************************************************************/
#define ToNode(lpSql, idx) (&((lpSql)[idx]))
#define ToString(lpSql, idx) (&((lpSql)->node.root.lpStringArea[idx]))
/***************************************************************************/
RETCODE INTFUNC Parse(LPSTMT, LPISAM, LPUSTR, SDWORD, LPSQLTREE FAR *);
SQLNODEIDX INTFUNC AllocateNode(LPSQLTREE FAR *, UWORD);
STRINGIDX INTFUNC AllocateSpace(LPSQLTREE FAR *, SWORD);
STRINGIDX INTFUNC AllocateString(LPSQLTREE FAR *, LPUSTR);
void INTFUNC FreeTree(LPSQLTREE);
/***************************************************************************/