📄 absexpressions.pas
字号:
// SUB operation
procedure SubData;
// ADD operation
procedure AddData;
// MUL operation
procedure MulData;
// DIV operation
procedure DivData;
// ABS operation
procedure GetABSValue;
// ACOS operation
procedure GetACOSValue;
// ASIN operation
procedure GetASINValue;
// ATAN operation
procedure GetATANValue;
// CEIL operation
procedure GetCEILValue;
// COS operation
procedure GetCOSValue;
// EXP operation
procedure GetEXPValue;
// FLOOR operation
procedure GetFLOORValue;
// LOG operation
procedure GetLOGValue;
// POWER operation
procedure GetPOWERValue;
// RAND operation
procedure GetRANDValue;
// ROUND operation
procedure GetROUNDValue;
// SIGN operation
procedure GetSIGNValue;
// SIN operation
procedure GetSINValue;
// SQR operation
procedure GetSQRValue;
// SQRT operation
procedure GetSQRTValue;
public
// Return Data Value
function GetDataValue: TABSVariant; override;
// get value data type
function GetDataType: TABSAdvancedFieldType; override;
end;
TABSExprNodeAggregated = class(TABSExprNode)
private
count: integer;
distinct: Boolean;
AvgSum: TABSVariant;
public
// Constructors
constructor Create(Op: TABSDataOperator); overload;
constructor Create(Op: TABSDataOperator;
distinct: boolean;
Node: TABSExprNode); overload;
// Destructor
destructor Destroy; override;
// Return Data Value
function GetDataValue: TABSVariant; override;
// return Type of Data
function GetDataType: TABSAdvancedFieldType; override;
// return Size of Data (for strings and arrays)
function GetDataSize: Integer; override;
// is expression contains aggregated function
function IsAggregated: Boolean; override;
function IsAggregatedCountAll: Boolean; override;
function CanBeAssigned(AO, ParentQueryAO: TABSAO;
ParentCursor: TABSCursor; ForHavingClause: Boolean = False): Boolean; override;
// Init for aggregated functions
procedure Init; override;
// Accumulate for group functions
procedure Accumulate; override;
procedure SetCountAll(RecordCount: Integer); override;
// check if agregate expr, const or only grouped fields are used
function CanBeUsedInGroupBy(GroupByFields: String): Boolean; override;
end;
TABSExprNodeCast = class(TABSExprNode)
private
FCastType: TABSAdvancedFieldType; // Type for convertation
LCastSizeNode: TABSExprNode;
public
constructor Create(Node: TABSExprNode;
CastType: TABSAdvancedFieldType;
CastSizeNode: TABSExprNode = nil); overload;
// Return Data Value
function GetDataValue: TABSVariant; override;
// return Type of Data
function GetDataType: TABSAdvancedFieldType; override;
// return Size of Data (for strings and arrays)
function GetDataSize: Integer; override;
end;
TABSExprNodeCase = class(TABSExprNode)
private
FWhenExpressions: TList;
FResultExpressions: TList;
FElseResultExpression: TABSExprNode;
FInputExpression: TABSExprNode;
FCoalesceNodes: TABSExprNodeArray;
FIsCoalesceExpression: Boolean;
public
// Constructors
procedure CreateInit;
constructor CreateSimpleCase(InputExpression: TABSExprNode);
constructor CreateSearchedCase;
constructor CreateCoalesce(Nodes: TABSExprNodeArray);
// Destructor
destructor Destroy; override;
// Return Data Value
function GetDataValue: TABSVariant; override;
// return Type of Data
function GetDataType: TABSAdvancedFieldType; override;
// return Size of Data (for strings and arrays)
function GetDataSize: Integer; override;
procedure AddWhenExpression(Node: TABSExprNode);
procedure AddResultExpression(Node: TABSExprNode);
procedure SetElseResultExpression(Node: TABSExprNode);
end;
TABSExprNodeBlob = class(TABSExprNode)
private
procedure MimeToBin;
public
function GetDataValue: TABSVariant; override;
function GetDataType: TABSAdvancedFieldType; override;
function GetDataSize: Integer; override;
end;
TABSExprNodeStringFunction = class(TABSExprNode)
protected
function InitStringValue: Boolean;
protected
procedure Concat;
procedure Upper;
procedure Lower;
procedure Trim;
procedure LTrim;
procedure RTrim;
procedure Length;
procedure Pos;
procedure Substring;
public
// Return Data Value
function GetDataValue: TABSVariant; override;
// return Type of Data
function GetDataType: TABSAdvancedFieldType; override;
// return Size of Data (for strings and arrays)
function GetDataSize: Integer; override;
end;
TABSExprNodeSystem = class(TABSExprNode)
private
FTableName: String;
FColumnName: String;
FInMemory: Boolean;
FTable: TDataSet;
FFieldType: TABSAdvancedFieldType;
FRowNumValue: integer;
private
procedure LastAutoInc;
procedure RowNum;
public
// creates
constructor Create(Operator: TABSDataOperator; SessionName, DatabaseName, TableName, ColumnName: String; InMemory: Boolean); overload;
// Destructor
destructor Destroy; override;
// Return Data Value
function GetDataValue: TABSVariant; override;
// return Type of Data
function GetDataType: TABSAdvancedFieldType; override;
// return Size of Data (for strings and arrays)
function GetDataSize: Integer; override;
end;
TABSExprNodeDateFunction = class(TABSExprNode)
private
DateFormater: TDateFormater;
ExtractDateTimeField: TABSDateTimeExtractField;
// ToDate
procedure ToDate;
// ToString
procedure ToString;
// Extract
procedure Extract;
public
// Constructor
constructor Create(Op: TABSDataOperator;
Node: TABSExprNode;
FormatStr: String); overload;
constructor Create(Op: TABSDataOperator;
ExtractField: TABSDateTimeExtractField;
ExtractSource: TABSExprNode); overload;
// Destructor
destructor Destroy; override;
// Return Data Value
function GetDataValue: TABSVariant; override;
// return Type of Data
function GetDataType: TABSAdvancedFieldType; override;
// return Size of Data (for strings and arrays)
function GetDataSize: Integer; override;
end;
TCheckResultsMethod = function: Boolean of object;
TABSExprNodeSubquery = class(TABSExprNode)
private
FMustHaveOneField: Boolean;
FMustHaveOneRow: Boolean;
FValue: TABSVariant;
FFieldValues: array of TABSVariant;
LDataset: TDataset;
LLexer: TABSLexer;
LAO: TABSAO;
LCursor: TABSCursor;
LCursorRecordBuffer: TABSRecordBuffer;
FSubquery: TObject;// TABSSQLUnion
FCommandNo: Integer;
FTokenNo: Integer;
LValueToCheck: TABSVariant;
FPriorValueToCheck: TABSVariant;
FPriorResult: Boolean;
FPriorResultInitalized: Boolean;
FCompareOperator: TABSDataOperator;
FCompareQuantifier: TABSQuantifier;
FCorrelated: Boolean;
function CheckGetDataValue: Boolean;
function CheckGetFieldValues: Boolean;
function CheckExists: Boolean;
function CheckIsValueIn: Boolean;
function CheckQuantifiedCompare: Boolean;
function RunQueryAndCheckResults(CheckMethod: TCheckResultsMethod): Boolean;
public
// Constructor
constructor Create(MustHaveOneField: Boolean; MustHaveOneRow: Boolean;
Dataset: TDataset; Lexer: TABSLexer);
destructor Destroy; override;
// process assign cursor
procedure AssignCursor(Cursor: TABSCursor; ParentQueryAO: TABSAO; ParentCursor: TABSCursor); override;
// process assign New Cursor Buffer
procedure AssignCursorBuffer(Buffer: TABSRecordBuffer; ApplyToParentQueryFields: Boolean); override;
// process assign AO
procedure AssignAO(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor); override;
function CanBeAssigned(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor; ForHavingClause: Boolean = False): Boolean; override;
// Return Data Value
function GetDataValue: TABSVariant; override;
// calc subquery field values again
procedure ResetSubqueryFieldValues; override;
// Return subquery field value
function GetSubqueryFieldValue(FieldNo: Integer): TABSVariant; override;
// return Type of Data
function GetDataType: TABSAdvancedFieldType; override;
// return Data Size
function GetDataSize: Integer; override;
// EXISTS subquery
function Exists: Boolean;
// IN subquery
function IsValueIn(Value: TABSVariant): Boolean;
// > ALL subquery
function QuantifiedCompare(Operator: TABSDataOperator;
Quantifier: TABSQuantifier; Value: TABSVariant): Boolean;
end;
// get operator name
function GetOperatorName(op: TABSDataOperator): String;
// Return FieldType
function GetFieldType(const TypeName: string): TABSAdvancedFieldType;
procedure FillFieldNames(List: TStringList; const Names: String);
// "<" => ">", "=" => "="
function ReverseComparisonOperator(CompOp: TABSDataOperator): TABSDataOperator;
// "<" => ">=", "=" => "<>"
function InvertComparisonOperator(CompOp: TABSDataOperator): TABSDataOperator;
function IsNonConstantExpression(Value: TABSVariant): Boolean;
implementation
uses ABSMain, ABSCompression, ABSSQLProcessor, ABSLocalEngine, ABSDecUtil,
Math, ABSStrUtils, ABSDecimalRounding;
//------------------------------------------------------------------------------
// get operator name
//------------------------------------------------------------------------------
function GetOperatorName(op: TABSDataOperator): String;
begin
case op of
doNOT: Result := 'NOT';
doAND: Result := 'AND';
doOR: Result := 'OR';
doEQ: Result := '=';
doNE: Result := '<>';
doLT: Result := '<';
doGT: Result := '>';
doLE: Result := '<=';
doGE: Result := '>=';
doLIKE: Result := 'LIKE';
doNOTLIKE: Result := 'NOT LIKE';
doISNULL: Result := 'IS NULL';
doISNOTNULL: Result := 'IS NOT NULL';
doADD: Result := '+';
doSUB: Result := '-';
doMUL: Result := '*';
doDIV: Result := '/';
doCONCAT: Result := '||';
doUPPER: Result := 'UPPER';
doLOWER: Result := 'LOWER';
doTRIM: Result := 'TRIM';
doLTRIM: Result := 'LTRIM';
doRTRIM: Result := 'RTRIM';
doSUM: Result := 'SUM';
doAVG: Result := 'AVG';
doMIN: Result := 'MIN';
doMAX: Result := 'MAX';
doCOUNT: Result := 'COUNT';
doCOUNTALL: Result := 'COUNT(*)';
else Result:='unknown';
end;
end;//GetOperatorName
//------------------------------------------------------------------------------
// Return FieldType
//------------------------------------------------------------------------------
function GetFieldType(const TypeName: string): TABSAdvancedFieldType;
var
i: Integer;
s: String;
begin
Result := aftUnknown;
s := UpperCase(TypeName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -