⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 absrelationalalgebra.pas

📁 Absolute Database 是来替代BDE[Borland数据库引擎]的用于Delphi 和 C++ Builder 开发用的数据库引擎. 它小巧, 高速, 健壮, 易于使用. 它能直接编译进
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    begin
      FResultDataset.Close;
      try
        if (TABSTable(FResultDataset).Temporary) then
          TABSTable(FResultDataset).DeleteTable;
      except
      end;
      FResultDataset.Free;
    end;
  if (FResultFieldsOrder <> nil) then
    FResultFieldsOrder.Free;
  if (FLeftAO <> nil) then
    FLeftAO.Free;
  if (FRightAO <> nil) then
    FRightAO.Free;
  if (FFilterExpr <> nil) then
    TABSExpression(FFilterExpr).Free;
  FreeResultIndexLists;
  FValue.Free;
  inherited Destroy;
end; // Destroy


//------------------------------------------------------------------------------
// getting all result records
//------------------------------------------------------------------------------
procedure TABSAO.Execute(IsRootAO: Boolean; ParentQueryAO: TABSAO; ParentCursor: TABSCursor);
var
  p: Pointer;
  IsCreated: Boolean;
begin
  FIsRootAO := IsRootAO;

  // filter
  if (not FIsAOTable) then
   if (FFilterExpr <> nil) then
     TABSExpression(FFilterExpr).AssignAO(Self, ParentQueryAO, ParentCursor);

  if (FLeftAO <> nil) then
    FLeftAO.Execute(False, ParentQueryAO, ParentCursor);
  if (FRightAO <> nil) then
    FRightAO.Execute(False, ParentQueryAO, ParentCursor);

  // optimize join

  if ((FLeftAO <> nil) and (FRightAO <> nil)) then
    if (Self is TABSAOJoin) then
      if (TABSAOJoin(Self).FJoinType in [ajtInner,ajtFullOuter]) then
      // bug-fix: 4.84 - speed up join with filtered table when LeftAO has much more records than RightAO
//        if (TABSTable(FLeftAO.ResultDataset).Handle.SQLFilterExpression = nil) and
//           (TABSTable(FRightAO.ResultDataset).Handle.SQLFilterExpression = nil) then
          if (FRightAO.ResultDataset.RecordCount < FLeftAO.ResultDataset.RecordCount) then
            begin
              p := FLeftAO;
              FLeftAO := FRightAO;
              FRightAO := p;
              p := TABSAOJoin(Self).FFields1;
              TABSAOJoin(Self).FFields1 := TABSAOJoin(Self).FFields2;
              TABSAOJoin(Self).FFields2 := p;
            end;

  if (FIsAOGroupBy) then
   if (not TABSAOGroupBy(Self).FAllFields) then
     if (TABSAOGroupBy(Self).FTempDataset = nil) and (FLeftAO <> nil) then
      begin
       TABSAOGroupBy(Self).FTempDataset := TABSTable.Create(nil);
       TABSTable(TABSAOGroupBy(Self).FTempDataset).DatabaseName :=
        TABSTable(FLeftAO.FResultDataset).DatabaseName;
       TABSTable(TABSAOGroupBy(Self).FTempDataset).SessionName :=
        TABSTable(FLeftAO.FResultDataset).SessionName;
       TABSTable(TABSAOGroupBy(Self).FTempDataset).TableName :=
        TABSTable(FLeftAO.FResultDataset).TableName;
       TABSTable(TABSAOGroupBy(Self).FTempDataset).InMemory :=
        TABSTable(FLeftAO.FResultDataset).InMemory;
       TABSTable(TABSAOGroupBy(Self).FTempDataset).Temporary :=
        TABSTable(FLeftAO.FResultDataset).Temporary;
       TABSTable(TABSAOGroupBy(Self).FTempDataset).ReadOnly := True;

       try
        TABSAOGroupBy(Self).FTempDataset.Open;
       except
        raise EABSException.Create(10304,ErrorLCannotOpenTable,
          [TABSTable(TABSAOGroupBy(Self).FTempDataset).TableName,
           Word(TABSTable(TABSAOGroupBy(Self).FTempDataset).InMemory)]);
       end;

       if (TABSTable(FLeftAO.FResultDataset).IsDistinctApplied) then
         TABSTable(TABSAOGroupBy(Self).FTempDataset).ApplyDistinct(TABSTable(FLeftAO.FResultDataset))
       else
         TABSTable(TABSAOGroupBy(Self).FTempDataset).IndexName :=
           TABSTable(FLeftAo.FResultDataset).IndexName;
      end; // FIsAOGroupBy

 if (FTopRowCount > 0) and (FResultIndexFieldsList <> nil) and (FLeftAO <> nil) then
  begin
   TABSTable(FLeftAo.FResultDataset).IndexName :=
     TABSTable(FLeftAo.FResultDataset).FindOrCreateIndex(
      FResultIndexFieldsList,FResultIndexAscDescFieldsList,FResultIndexCaseInsFieldsList,IsCreated)
  end;

 if ((FLeftAO <> nil) or (FRightAO <> nil)) then
  DoMaterialize;
 if (FResultIndexFieldsList <> nil) then
  InternalSetIndex(True);
end;// Execute


//------------------------------------------------------------------------------
// LockTables
//------------------------------------------------------------------------------
function TABSAO.LockTables: Boolean;
begin
  if (FIsAOTable) then
    begin
      if (ResultDataset.Active) then
        Result := TABSTable(ResultDataset).Handle.LockTable(ltS,
                      SelectTrialTableLockRetries, SelectTrialTableLockDelay)
      else
        Result := False;
      FIsLocked := Result;
    end
  else
    begin
      Result := True;
      if (FLeftAO <> nil) then
        Result := Result and FLeftAO.LockTables;
      if (FRightAO <> nil) then
       if (Result) then
         Result := Result and FRightAO.LockTables;
    end;
end;// LockTables


//------------------------------------------------------------------------------
// UnlockTables
//------------------------------------------------------------------------------
function TABSAO.UnlockTables: Boolean;
begin
  if (FIsAOTable) then
    begin
      if (FIsLocked) then
        if (ResultDataset.Active) then
           begin
             Result := TABSTable(ResultDataset).Handle.UnlockTable(ltS, True);
             FIsLocked := not Result;
           end
        else
          Result := False
      else
        Result := True;
    end
  else
    begin
      Result := True;
      if (FLeftAO <> nil) then
        Result := Result and FLeftAO.UnlockTables;
      if (FRightAO <> nil) then
        Result := Result and FRightAO.UnlockTables;
    end;
end;// UnlockTables


//------------------------------------------------------------------------------
// OpenTables
//------------------------------------------------------------------------------
function TABSAO.OpenTables: Boolean;
begin
  if (FIsAOTable) then
    begin
      try
        ResultDataset.Open;
        Result := True;
      except
        ResultDataset.Close;
        Result := False;
      end;
    end
  else
    begin
      Result := True;
      if (FLeftAO <> nil) then
        Result := Result and FLeftAO.OpenTables;
      if (FRightAO <> nil) then
        Result := Result and FRightAO.OpenTables;
    end;
end;// OpenTables


//------------------------------------------------------------------------------
// CloseTables
//------------------------------------------------------------------------------
function TABSAO.CloseTables: Boolean;
begin
  if (FIsAOTable) then
    begin
      try
        ResultDataset.Close;
        Result := True;
      except
        Result := False;
      end;
    end
  else
    begin
      Result := True;
      if (FLeftAO <> nil) then
        Result := Result and FLeftAO.CloseTables;
      if (FRightAO <> nil) then
        Result := Result and FRightAO.CloseTables;
    end;
end;// CloseTables


//------------------------------------------------------------------------------
// set filter
//------------------------------------------------------------------------------
procedure TABSAO.SetFilter(FilterExpr: TObject);
begin
 if (FFilterExpr = nil) then
   FFilterExpr := FilterExpr
 else
   begin
     TABSExpression(FFilterExpr).AddAndMoveNodesFromExpression(TABSExpression(FilterExpr));
     FilterExpr.Free;
   end;
end; // SetFilter


//------------------------------------------------------------------------------
// for SELECT INTO optimization
//------------------------------------------------------------------------------
procedure TABSAO.SetResultTable(InMemory, Immediate: Boolean; TableName: String; DatabaseName: String);
begin
  FResultInMemory := InMemory;
  FResultImmediate := Immediate;
  FResultTableName := TableName;
  FResultDatabaseName := DatabaseName;
end; // SetResultTable


//------------------------------------------------------------------------------
// sets Top row count
//------------------------------------------------------------------------------
procedure TABSAO.SetTopRowCount(FirstRowNo, TopRowCount: integer);
begin
  if (not FDistinctApplied) and
     ((FResultIndexFieldsList = nil) or
      ((FResultIndexFieldsList <> nil) and (FResultIndexFieldsList.Count = 0))) then
    begin
      FTopRowCount := TopRowCount;
      if (FirstRowNo < 0) then
        FFirstRowNo := 1
      else
        FFirstRowNo := FirstRowNo;
    end;
end;// SetTopRowCount


//------------------------------------------------------------------------------
// applies distinct
//------------------------------------------------------------------------------
procedure TABSAO.ApplyDistinct(DistinctFields: String);
var
  DistinctFieldList: TStringList;

procedure ApplyDistinctToChild(AO: TABSAO);
var
  ChildDistinctFields: String;
  i: integer;
begin
  if not (AO is TABSAOTable) then
    begin
      ChildDistinctFields := '';
      for i := 0 to FFieldCount-1 do
        if (FFieldLinks[i].AO = AO) and (not FFieldLinks[i].IsHidden) then
          begin
            if (ChildDistinctFields <> '') then
              ChildDistinctFields := ChildDistinctFields+';';
            ChildDistinctFields := ChildDistinctFields +
              TABSAO(FFieldLinks[i].AO).FFieldLinks[FFieldLinks[i].FieldNo].FieldName;
          end;
      if (ChildDistinctFields <> '') then
        AO.ApplyDistinct(ChildDistinctFields);
    end;
end;

procedure FillDistinctFieldsMap;
var
  i,j: integer;
begin
  SetLength(FDistinctFieldsMap, DistinctFieldList.Count);
  for i := 0 to DistinctFieldList.Count-1 do
    for j := 0 to FFieldCount-1 do
      if (AnsiUpperCase(FFieldLinks[j].FieldName) = AnsiUpperCase(DistinctFieldList[i])) then
        begin
          FDistinctFieldsMap[i] := j;
          break;
        end;
end;

begin
  DistinctFieldList := TStringList.Create;
  try
    FillFieldNames(DistinctFieldList,DistinctFields);
    FDistinctApplied := (DistinctFieldList.Count > 0);
    if (FDistinctApplied) then
      begin
        FDistinctFields := DistinctFields;
        FDistinctFieldCount := DistinctFieldList.Count;
        FillDistinctFieldsMap;
        // bug-fix 4.85 - incorrect when condition on hidden join fields
        if (FFilterExpr = nil) then
          if (Self is TABSAOJoin) then
            begin
              if (FLeftAO <> nil) then
                ApplyDistinctToChild(FLeftAO);
              if (FRightAO <> nil) then
                ApplyDistinctToChild(FRightAO);
            end;
      end;
  finally
    DistinctFieldList.Free;
  end;
end; // ApplyDistinct


//------------------------------------------------------------------------------
// sets projection for other TABSAO
//------------------------------------------------------------------------------
procedure TABSAO.SetResultFields(var FieldRefs: array of TABSSelectListItem;
                                  bDistinct: Boolean);
var i,j,k,x,res: integer;
    fname,tname: string;
    aDistinctFields: String;
begin
 aDistinctFields := '';
 j := Length(FieldRefs);
 if (j <= 0) then
  begin
   FieldExists('*','',true,FResultFieldsOrder);
  end
 else
  for i := 0 to j-1 do
   begin
    if (FieldRefs[i].AllFields) then
     fname := '*'
    else
     fname := FieldRefs[i].FieldName;
    tname := FieldRefs[i].TableName;
    if (FieldRefs[i].IsExpression) then
      if ((not TABSExpression(FieldRefs[i].ValueExpr).IsAggregated) or (FIsAOGroupBy)) then
       begin
        inc(FFieldCount);
        SetLength(FFieldLinks,FFieldCount);
        FFieldLinks[FFieldCount-1].Expr := FieldRefs[i].ValueExpr;
        TABSExpression(FFieldLinks[FFieldCount-1].Expr).AssignAO(self, nil, nil);
        // create new field for this expression
        if (FieldRefs[i].Pseudonym <> '') then
         // pseudonim specified
         FFieldLinks[FFieldCount-1].FieldName := FieldRefs[i].Pseudonym
        else
         // random name
         FFieldLinks[FFieldCount-1].FieldName := GetTemporaryName(ABSExpressionFieldName);
        FFieldLinks[FFieldCount-1].DisplayName := FFieldLinks[FFieldCount-1].FieldName;
        // get field type
        FFieldLinks[FFieldCount-1].FieldType :=
          TABSExpression(FieldRefs[i].ValueExpr).GetDataType;
        // get field size
        FFieldLinks[FFieldCount-1].FieldSize :=
          TABSExpression(FieldRefs[i].ValueExpr).GetDataSize;
        // get field precision
        FFieldLinks[FFieldCount-1].FieldPrecision :=
          TABSExpression(FieldRefs[i].ValueExpr).GetPrecision;
        // AO
        FFieldLinks[FFieldCount-1].AO := self;
        FFieldLinks[FFieldCount-1].Dataset := nil;
        FFieldLinks[FFieldCount-1].IsHidden := false;
        FFieldLinks[FFieldCount-1].IsExpression := true;
        FFieldLinks[FFieldCount-1].IsAggregate :=
          TABSExpression(FieldRefs[i].ValueExpr).IsAggregated;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -