mirror of https://github.com/tongzx/nt5src
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
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);
|
|
/***************************************************************************/
|