📄 absexpressions.pas
字号:
var
Value: TABSVariant;
begin
Value := GetValue(false);
if Value = nil then
raise EABSException.Create(30110, ErrorGValueIsNull);
Result := Value.AsBoolean;
end;//GetResult
//------------------------------------------------------------------------------
// calc subquery field values again
//------------------------------------------------------------------------------
procedure TABSExpression.ResetSubqueryFieldValues;
begin
if FRootExprNode <> nil then
FRootExprNode.ResetSubqueryFieldValues;
end;// ResetSubqueryFieldValues
//------------------------------------------------------------------------------
// Return subquery field value
//------------------------------------------------------------------------------
function TABSExpression.GetSubqueryFieldValue(FieldNo: Integer): TABSVariant;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.GetSubqueryFieldValue(FieldNo)
else
Result := nil;
end;// GetSubqueryFieldValue
//------------------------------------------------------------------------------
// is expression contains aggregated function
//------------------------------------------------------------------------------
function TABSExpression.IsAggregated: Boolean;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.IsAggregated
else
Result := False;
end;//IsAggregated
//------------------------------------------------------------------------------
// is Count(*)
//------------------------------------------------------------------------------
function TABSExpression.IsAggregatedCountAll: Boolean;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.IsAggregatedCountAll
else
Result := False;
end;// IsAggregatedCountAll
//------------------------------------------------------------------------------
// Init for aggregated functions
//------------------------------------------------------------------------------
procedure TABSExpression.Init;
begin
if FRootExprNode <> nil then
FRootExprNode.Init;
end;//Init
//------------------------------------------------------------------------------
// Accumulate for group functions
//------------------------------------------------------------------------------
procedure TABSExpression.Accumulate;
begin
if FRootExprNode <> nil then
FRootExprNode.Accumulate;
end;//Accumulate
//------------------------------------------------------------------------------
// SetCountAll
//------------------------------------------------------------------------------
procedure TABSExpression.SetCountAll(RecordCount: Integer);
begin
if FRootExprNode <> nil then
FRootExprNode.SetCountAll(RecordCount);
end;// SetCountAll
//------------------------------------------------------------------------------
// process assign AO
//------------------------------------------------------------------------------
procedure TABSExpression.AssignAO(AO, ParentQueryAO: TABSAO; ParentCursor: TABSCursor);
begin
if (FRootExprNode <> nil) then
begin
FRootExprNode.AssignAO(AO, ParentQueryAO, ParentCursor);
FRootExprNode.PatchWideStrings;
end;
end;//AssignAO
//------------------------------------------------------------------------------
// process assign Cursor and its RecordBuffer
//------------------------------------------------------------------------------
procedure TABSExpression.AssignCursor(Cursor: TABSCursor; ParentQueryAO: TABSAO; ParentCursor: TABSCursor);
begin
if (FRootExprNode <> nil) then
begin
FRootExprNode.AssignCursor(Cursor, ParentQueryAO, ParentCursor);
FRootExprNode.PatchWideStrings;
end;
end;//AssignCursor
//------------------------------------------------------------------------------
// process assign New Cursor Buffer
//------------------------------------------------------------------------------
procedure TABSExpression.AssignCursorBuffer(Buffer: TABSRecordBuffer; ApplyToParentQueryFields: Boolean);
begin
if (FRootExprNode <> nil) then
begin
FRootExprNode.AssignCursorBuffer(Buffer, ApplyToParentQueryFields);
FRootExprNode.PatchWideStrings;
end;
end;//AssignCursorBuffer
//------------------------------------------------------------------------------
// return Expression DataSize
//------------------------------------------------------------------------------
function TABSExpression.GetDataSize: Integer;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.getDataSize
else
Result := 0;
end;//getDataSize
//------------------------------------------------------------------------------
// return Size of Data (for strings and arrays)
//------------------------------------------------------------------------------
function TABSExpression.GetPrecision: Integer;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.GetPrecision
else
Result := 0;
end;//GetPrecision
//------------------------------------------------------------------------------
// return Expression DataType
//------------------------------------------------------------------------------
function TABSExpression.GetDataType: TABSAdvancedFieldType;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.getDataType
else
Result := aftUnknown;
end;//GetDataType
//------------------------------------------------------------------------------
// is expression contains no nodes
//------------------------------------------------------------------------------
function TABSExpression.IsEmpty: Boolean;
begin
Result := (FRootExprNode = nil);
if (not Result) then
if (FRootExprNode is TABSExprNodeBoolean) then
Result := (FRootExprNode.Children.Count = 0);
end;//IsEmpty
//------------------------------------------------------------------------------
// is expression a Field (for join)
//------------------------------------------------------------------------------
function TABSExpression.IsField: Boolean;
begin
Result := False;
if FRootExprNode <> nil then
Result := FRootExprNode is TABSExprNodeField;
end;//IsField
//------------------------------------------------------------------------------
// is expression a combination of fields
//------------------------------------------------------------------------------
function TABSExpression.IsFieldsExpression: Boolean;
var
I: Integer;
begin
Result := False;
if FRootExprNode <> nil then
begin
if (FRootExprNode is TABSExprNodeField) then
begin
Result := True;
Exit;
end;
for I := 0 to FRootExprNode.Children.Count - 1 do
begin
if (TABSExprNode(FRootExprNode.Children[I]) is TABSExprNodeField) then
begin
Result := True;
Exit;
end;
end;
end;
end;
//------------------------------------------------------------------------------
// Move AndNodes To RootNode
//------------------------------------------------------------------------------
procedure TABSExpression.MoveAndNodesToRoot;
var
i: Integer;
begin
if (FRootExprNode.Operator = doAND) then
begin
i := 0;
while i < FRootExprNode.Children.Count do
begin
if (TABSExprNode(FRootExprNode.Children[i]).Operator = doAND) then
begin
while TABSExprNode(FRootExprNode.Children[i]).Children.Count > 0 do
begin
FRootExprNode.Children.Add(TABSExprNode(FRootExprNode.Children[i]).Children[0]);
TABSExprNode(FRootExprNode.Children[i]).Children.Delete(0);
end;
TABSExprNode(FRootExprNode.Children[i]).Free;
FRootExprNode.Children.Delete(i);
Continue;
end;
Inc(i);
end;
end;
end;//MoveAndNodesToRoot
//------------------------------------------------------------------------------
// Field Name, Table Name
//------------------------------------------------------------------------------
procedure TABSExpression.GetFieldInfo(var TableName, FieldName: String);
begin
if (IsField) then
begin
TableName := TABSExprNodeField(FRootExprNode).FTableName;
FieldName := TABSExprNodeField(FRootExprNode).FFieldName;
end
else
raise EABSException.Create(30198, ErrorGNodeIsNotField);
end;// GetFieldInfo
//------------------------------------------------------------------------------
// makes filter from related parts and sets it to AO
//------------------------------------------------------------------------------
procedure TABSExpression.ApplyFilterParts(AO: TABSAO; ParentQueryAO: TABSAO;
ParentCursor: TABSCursor;
AllowRecurse: Boolean = True; ForHavingClause: Boolean = False);
var
NodesToDelete: TList;
Node: TABSExprNode;
bRecurse: Boolean;
i: Integer;
FilterRootNode: TABSExprNode;
begin
FilterRootNode := nil;
bRecurse := AllowRecurse;
// don't set filter to outer join childs
if bRecurse and (AO is TABSAOJoin) then
bRecurse := not TABSAOJoin(AO).OuterJoin;
// try to apply to AO children
if (bRecurse) then
begin
if (AO.FLeftAO <> nil) then
ApplyFilterParts(AO.FLeftAO, ParentQueryAO, ParentCursor, AllowRecurse, ForHavingClause);
if (AO.FRightAO <> nil) then
ApplyFilterParts(AO.FRightAO, ParentQueryAO, ParentCursor, AllowRecurse, ForHavingClause);
end;
// traverse tree by factors: (...) AND (...) AND (...)
if (FRootExprNode <> nil) then
begin
NodesToDelete := TList.Create;
try
// -> (...) AND (...) AND (...) ?
if (FRootExprNode is TABSExprNodeBoolean) and
(FRootExprNode.Operator = doAND) then
for i:=0 to FRootExprNode.Children.Count-1 do
begin
Node := FRootExprNode.Children[i];
// (...) can be used by the AO?
if (Node.CanBeAssigned(AO, ParentQueryAO, ParentCursor, ForHavingClause)) then
begin
// no FilterRootNode
if FilterRootNode = nil then
FilterRootNode := Node
else
// FilterRootNode=AND ( ex: a=b AND c=d )
if (FilterRootNode is TABSExprNodeBoolean) and
(FilterRootNode.Operator = doAND) then
FilterRootNode.Children.Add(Node)
else
// single FilterRootNode ( ex: a=b ) - converting to AND
FilterRootNode := TABSExprNodeBoolean.Create(doAND,
FilterRootNode, Node);
NodesToDelete.Add(Node);
end;
// -> AND (...)
end
else
// (...)
begin
if (FRootExprNode.CanBeAssigned(AO, ParentQueryAO, ParentCursor, ForHavingClause)) then
begin
FilterRootNode := FRootExprNode;
FRootExprNode := nil;
end;
end;
// delete used nodes
for i:=0 to NodesToDelete.Count-1 do
begin
FRootExprNode.Children.Delete(
FRootExprNode.Children.IndexOf(NodesToDelete[i]));
end;
// set extracted filter
if FilterRootNode <> nil then
AO.SetFilter(TABSExpression.Create(FilterRootNode));
// no children?
if (FRootExprNode <> nil) then
if (FRootExprNode.Children.Count = 0) then
begin
FRootExprNode.Free;
FRootExprNode := nil;
end;
finally
NodesToDelete.Free;
end;
end;
end;// ApplyFilterParts
//------------------------------------------------------------------------------
// gets current token
//------------------------------------------------------------------------------
procedure TABSExpression.ReplacePseudonyms(SelectList: array of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -