📄 myldbexpressions.pas
字号:
FRootExprNode := ParseRowSubquery(False, False);
end;// ParseForRowSubqueryExpression
//------------------------------------------------------------------------------
// Return Variant
//------------------------------------------------------------------------------
function TMYLDBExpression.GetValue(TrueFalseNullLogic: boolean): TMYLDBVariant;
begin
if FRootExprNode <> nil then
begin
Result := FRootExprNode.GetDataValue;
if ( Result.IsNull and (not TrueFalseNullLogic) ) then
Result.AsBoolean := False;
end
else
Result := nil;
end;//GetValue
//------------------------------------------------------------------------------
// Get Boolean result
//------------------------------------------------------------------------------
function TMYLDBExpression.GetResult: Boolean;
var
Value: TMYLDBVariant;
begin
Value := GetValue(false);
if Value = nil then
raise EMYLDBException.Create(30110, ErrorGValueIsNull);
Result := Value.AsBoolean;
end;//GetResult
//------------------------------------------------------------------------------
// calc subquery field values again
//------------------------------------------------------------------------------
procedure TMYLDBExpression.ResetSubqueryFieldValues;
begin
if FRootExprNode <> nil then
FRootExprNode.ResetSubqueryFieldValues;
end;// ResetSubqueryFieldValues
//------------------------------------------------------------------------------
// Return subquery field value
//------------------------------------------------------------------------------
function TMYLDBExpression.GetSubqueryFieldValue(FieldNo: Integer): TMYLDBVariant;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.GetSubqueryFieldValue(FieldNo)
else
Result := nil;
end;// GetSubqueryFieldValue
//------------------------------------------------------------------------------
// is expression contains aggregated function
//------------------------------------------------------------------------------
function TMYLDBExpression.IsAggregated: Boolean;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.IsAggregated
else
Result := False;
end;//IsAggregated
//------------------------------------------------------------------------------
// is Count(*)
//------------------------------------------------------------------------------
function TMYLDBExpression.IsAggregatedCountAll: Boolean;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.IsAggregatedCountAll
else
Result := False;
end;// IsAggregatedCountAll
//------------------------------------------------------------------------------
// Init for aggregated functions
//------------------------------------------------------------------------------
procedure TMYLDBExpression.Init;
begin
if FRootExprNode <> nil then
FRootExprNode.Init;
end;//Init
//------------------------------------------------------------------------------
// Accumulate for group functions
//------------------------------------------------------------------------------
procedure TMYLDBExpression.Accumulate;
begin
if FRootExprNode <> nil then
FRootExprNode.Accumulate;
end;//Accumulate
//------------------------------------------------------------------------------
// SetCountAll
//------------------------------------------------------------------------------
procedure TMYLDBExpression.SetCountAll(RecordCount: Integer);
begin
if FRootExprNode <> nil then
FRootExprNode.SetCountAll(RecordCount);
end;// SetCountAll
//------------------------------------------------------------------------------
// process assign AO
//------------------------------------------------------------------------------
procedure TMYLDBExpression.AssignAO(AO, ParentQueryAO: TMYLDBAO; ParentCursor: TMYLDBCursor);
begin
if (FRootExprNode <> nil) then
begin
FRootExprNode.AssignAO(AO, ParentQueryAO, ParentCursor);
FRootExprNode.PatchWideStrings;
end;
end;//AssignAO
//------------------------------------------------------------------------------
// process assign Cursor and its RecordBuffer
//------------------------------------------------------------------------------
procedure TMYLDBExpression.AssignCursor(Cursor: TMYLDBCursor; ParentQueryAO: TMYLDBAO; ParentCursor: TMYLDBCursor);
begin
if (FRootExprNode <> nil) then
begin
FRootExprNode.AssignCursor(Cursor, ParentQueryAO, ParentCursor);
FRootExprNode.PatchWideStrings;
end;
end;//AssignCursor
//------------------------------------------------------------------------------
// process assign New Cursor Buffer
//------------------------------------------------------------------------------
procedure TMYLDBExpression.AssignCursorBuffer(Buffer: TMYLDBRecordBuffer; ApplyToParentQueryFields: Boolean);
begin
if (FRootExprNode <> nil) then
begin
FRootExprNode.AssignCursorBuffer(Buffer, ApplyToParentQueryFields);
FRootExprNode.PatchWideStrings;
end;
end;//AssignCursorBuffer
//------------------------------------------------------------------------------
// return Expression DataSize
//------------------------------------------------------------------------------
function TMYLDBExpression.GetDataSize: Integer;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.getDataSize
else
Result := 0;
end;//getDataSize
//------------------------------------------------------------------------------
// return Size of Data (for strings and arrays)
//------------------------------------------------------------------------------
function TMYLDBExpression.GetPrecision: Integer;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.GetPrecision
else
Result := 0;
end;//GetPrecision
//------------------------------------------------------------------------------
// return Expression DataType
//------------------------------------------------------------------------------
function TMYLDBExpression.GetDataType: TMYLDBAdvancedFieldType;
begin
if FRootExprNode <> nil then
Result := FRootExprNode.getDataType
else
Result := aftUnknown;
end;//GetDataType
//------------------------------------------------------------------------------
// is expression contains no nodes
//------------------------------------------------------------------------------
function TMYLDBExpression.IsEmpty: Boolean;
begin
Result := (FRootExprNode = nil);
if (not Result) then
if (FRootExprNode is TMYLDBExprNodeBoolean) then
Result := (FRootExprNode.Children.Count = 0);
end;//IsEmpty
//------------------------------------------------------------------------------
// is expression a Field (for join)
//------------------------------------------------------------------------------
function TMYLDBExpression.IsField: Boolean;
begin
Result := False;
if FRootExprNode <> nil then
Result := FRootExprNode is TMYLDBExprNodeField;
end;//IsField
//------------------------------------------------------------------------------
// is expression a combination of fields
//------------------------------------------------------------------------------
function TMYLDBExpression.IsFieldsExpression: Boolean;
var
I: Integer;
begin
Result := False;
if FRootExprNode <> nil then
begin
if (FRootExprNode is TMYLDBExprNodeField) then
begin
Result := True;
Exit;
end;
for I := 0 to FRootExprNode.Children.Count - 1 do
begin
if (TMYLDBExprNode(FRootExprNode.Children[I]) is TMYLDBExprNodeField) then
begin
Result := True;
Exit;
end;
end;
end;
end;
//------------------------------------------------------------------------------
// Move AndNodes To RootNode
//------------------------------------------------------------------------------
procedure TMYLDBExpression.MoveAndNodesToRoot;
var
i: Integer;
begin
if (FRootExprNode.Operator = doAND) then
begin
i := 0;
while i < FRootExprNode.Children.Count do
begin
if (TMYLDBExprNode(FRootExprNode.Children[i]).Operator = doAND) then
begin
while TMYLDBExprNode(FRootExprNode.Children[i]).Children.Count > 0 do
begin
FRootExprNode.Children.Add(TMYLDBExprNode(FRootExprNode.Children[i]).Children[0]);
TMYLDBExprNode(FRootExprNode.Children[i]).Children.Delete(0);
end;
TMYLDBExprNode(FRootExprNode.Children[i]).Free;
FRootExprNode.Children.Delete(i);
Continue;
end;
Inc(i);
end;
end;
end;//MoveAndNodesToRoot
//------------------------------------------------------------------------------
// Field Name, Table Name
//------------------------------------------------------------------------------
procedure TMYLDBExpression.GetFieldInfo(var TableName, FieldName: String);
begin
if (IsField) then
begin
TableName := TMYLDBExprNodeField(FRootExprNode).FTableName;
FieldName := TMYLDBExprNodeField(FRootExprNode).FFieldName;
end
else
raise EMYLDBException.Create(30198, ErrorGNodeIsNotField);
end;// GetFieldInfo
//------------------------------------------------------------------------------
// makes filter from related parts and sets it to AO
//------------------------------------------------------------------------------
procedure TMYLDBExpression.ApplyFilterParts(AO: TMYLDBAO; ParentQueryAO: TMYLDBAO;
ParentCursor: TMYLDBCursor;
AllowRecurse: Boolean = True; ForHavingClause: Boolean = False);
var
NodesToDelete: TList;
Node: TMYLDBExprNode;
bRecurse: Boolean;
i: Integer;
FilterRootNode: TMYLDBExprNode;
begin
FilterRootNode := nil;
bRecurse := AllowRecurse;
// don't set filter to outer join childs
if bRecurse and (AO is TMYLDBAOJoin) then
bRecurse := not TMYLDBAOJoin(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 TMYLDBExprNodeBoolean) 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 TMYLDBExprNodeBoolean) and
(FilterRootNode.Operator = doAND) then
FilterRootNode.Children.Add(Node)
else
// single FilterRootNode ( ex: a=b ) - converting to AND
FilterRootNode := TMYLDBExprNodeBoolean.Create(doAND,
FilterRootNode, Node);
NodesToDelete.Add(Node);
end;
// -> AND (...)
end
else
// (...)
begin
if (FRootExprNode.CanBeAssigned(AO, ParentQueryAO, ParentCursor, ForHavingClause)) then
begin
FilterRootNode :=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -