📄 absrelationalalgebra.pas
字号:
else
begin
// projection is set
// insert into result table is unavailable due to possible hidden fields
if (not FIsRootAO) or (not FResultImmediate) then
begin
FResultTableName := '';
FResultDatabaseName := '';
end;
// perpare projection
for i := 0 to FResultFieldsOrder.ItemCount-1 do
begin
j := FResultFieldsOrder.Items[i];
if (FFieldLinks[j].IsHidden) then
raise EABSException.Create(10312,ErrorLCannotAccessHiddenField,[FTableName,
FFieldLinks[j].FieldName,FFieldLinks[j].DisplayName,j]);
if (FFieldLinks[j].DisplayName <> '') then
begin
FieldList.Add(FFieldLinks[j].FieldName);
AliasList.Add(FFieldLinks[j].DisplayName);
end;
end;
// prepare visible fields
for i := 0 to FFieldCount-1 do
begin
if (FFieldLinks[i].IsHidden) then continue;
(*DuplicateCount := 0;*)
Name := FFieldLinks[i].FieldName;
(*// 5.05 rename duplicate fields
if TABSTable(FResultDataset).AdvFieldDefs.Find(FFieldLinks[i].FieldName) <> nil then
repeat
Name := FFieldLinks[i].FieldName + '_' + IntToStr(DuplicateCount + 1);
Inc(DuplicateCount);
until TABSTable(FResultDataset).AdvFieldDefs.Find(Name) = nil;*)
FieldDef := TABSTable(FResultDataset).AdvFieldDefs.AddFieldDef;
FieldDef.Name := Name;
(*if FResultFieldsOrder.IndexOf(i) > -1 then
FieldList[FResultFieldsOrder.IndexOf(i)] := Name;*)
//FieldDef := TABSTable(FResultDataset).AdvFieldDefs.AddFieldDef;
//FieldDef.Name := FFieldLinks[i].FieldName;
if (FFieldLinks[i].FieldType = aftAutoInc) then
FieldDef.DataType := aftInteger
else
FieldDef.DataType := FFieldLinks[i].FieldType;
FieldDef.Size := FFieldLinks[i].FieldSize;
FieldDef.BLOBCompressionAlgorithm :=
TCompressionAlgorithm(FFieldLinks[i].BLOBCompressionAlgorithm);
FieldDef.BLOBCompressionMode := FFieldLinks[i].BLOBCompressionMode;
FieldDef.BLOBBlockSize := FFieldLinks[i].BLOBBlockSize;
end;
end; // result table
if (FTopRowCount > -1) then
if (FResultIndexFieldsList <> nil) then
TABSTable(FResultDataset).IndexName := CreateIndexForMaterialize(True);
// create table
if (FResultTableName <> '') then
begin
TABSTable(FResultDataset).DatabaseName := FResultDatabaseName;
TABSTable(FResultDataset).TableName := FResultTableName;
TABSTable(FResultDataset).InMemory := FResultInMemory;
TABSTable(FResultDataset).Temporary := False;
end // result table
else
begin
TABSTable(FResultDataset).InMemory := False;
TABSTable(FResultDataset).Temporary := True;
TABSTable(FResultDataset).DisableTempFiles := FDisableTempFiles;
repeat
TABSTable(FResultDataset).TableName := GetTemporaryName(ABSTemporaryTableName);
until (not (TABSTable(FResultDataset).Exists));
end; // temporary table
if (FDistinctApplied) then
CreateIndexForDistinct;
TABSTable(FResultDataset).CreateTable;
TABSTable(FResultDataset).Open;
end; // CreateTableForMaterialize
//------------------------------------------------------------------------------
// fill table
//------------------------------------------------------------------------------
{$DEFINE PROFILE}
procedure TABSAO.FillTableForMaterialize;
var i,j,k,d: Integer;
values: array of TABSVariant;
bOK: Boolean;
{$IFDEF PROFILE}
StartTime: Cardinal;
{$ENDIF}
begin
if (FDistinctApplied) then
begin
SetLength(values,FDistinctFieldCount);
for i := 0 to FDistinctFieldCount-1 do
values[i] := TABSVariant.Create;
end
else
FDistinctFieldCount := 0;
try
// filling table with data
First;
k := 0;
while Not Eof do
begin
{$IFDEF PROFILE}
StartTime := GetTickCount;
{$ENDIF}
inc(k);
// check TOP n?
// TOP n?
if (FTopRowCount > -1) then
begin
if (TABSDataset(FResultDataset).RecordCount >= FTopRowCount) then
break;
end;
// TOP first_row
if (FFirstRowNo > -1) then
begin
if (k < FFirstRowNo) then
begin
Next;
continue;
end;
end;
if (FFilterExpr <> nil) then
begin
// check filter
if (not TABSExpression(FFilterExpr).GetResult) then
begin
Next;
continue;
end;
end;
// check distinct
if (FDistinctApplied) then
begin
bOK := True;
for d := 0 to FDistinctFieldCount-1 do
begin
// read current record
GetFieldValue(FValue,FDistinctFieldsMap[d],false,true);
if (not TABSTable(FResultDataset).Bof) then
if (FValue.Compare(values[d],False,False,False) <> cmprEqual) then
bOK := False;
values[d].Assign(FValue,True);
end;//for
if ((bOK) and (not TABSTable(FResultDataset).Bof)) then
begin
// skip this record
Next;
Continue;
end;
end;
TABSTable(FResultDataset).Insert;
// not result table
j := 0;
for i := 0 to FFieldCount-1 do
begin
if (FFieldLinks[i].IsHidden) then continue;
CopyFieldValue(i,j);
inc(j);
end; // not result table
// insert record
if (not FDistinctApplied) then
TABSTable(FResultDataset).Post
else
// check distinct
if (TABSTable(FResultDataset).Handle.CheckConstraints(True)) then
TABSTable(FResultDataset).Post
else
TABSTable(FResultDataset).Cancel;
// go to next record
Next;
{$IFDEF PROFILE}
StartTime := GetTickCount - StartTime;
if StartTime > 0 then OutputDebugString(PChar(IntToStr(k) + ': ' + IntToStr(StartTime)));
//OutputDebugString(PChar(IntToStr(k)));
{$ENDIF}
end; // enf of inserting records loop
if (FTopRowCount > -1) then
FTopRowCount := -1;
finally
if (FDistinctApplied) then
begin
for i := 0 to FDistinctFieldCount-1 do
values[i].Free;
values := nil;
end;
end;
end; // FillTableForMaterialize
//------------------------------------------------------------------------------
// ReplaceInIndexAliasesToFields
//------------------------------------------------------------------------------
procedure TABSAO.ReplaceInIndexAliasesToFields(FieldList, AliasList,
FResultIndexFieldsList: TStringList);
var
i,j,k: Integer;
IsField: Boolean;
begin
for i := 0 to AliasList.Count-1 do
begin
// first check if alias is a real field name
IsField := False;
for j := 0 to FieldList.Count-1 do
if (AnsiUpperCase(AliasList[i]) = AnsiUpperCase(FieldList[j])) then
begin
IsField := True;
Break;
end;
if IsField then Continue;
//
for j := 0 to FResultIndexFieldsList.Count-1 do
if (AnsiUpperCase(AliasList[i]) = AnsiUpperCase(FResultIndexFieldsList[j])) then
FResultIndexFieldsList[j] := FieldList[i];
end;
end;// ReplaceInIndexAliasesToFields
//------------------------------------------------------------------------------
// finalize materialize
//------------------------------------------------------------------------------
procedure TABSAO.FinalizeMaterialize(
FieldList: TStringList;
AliasList: TStringList
);
var i,j: Integer;
begin
if (FResultIndexFieldsList <> nil) then
if (not ((FTopRowCount > -1) or (FDistinctApplied))) then
begin
ReplaceInIndexAliasesToFields(FieldList, AliasList, FResultIndexFieldsList);
TABSTable(FResultDataset).IndexName := CreateIndexForMaterialize(False);
end;
TABSTable(FResultDataset).ApplyProjection(FieldList,AliasList);
// move field links to the result dataset
if (FResultFieldsOrder.ItemCount <= 0) then
begin
j := 0;
// not result table
for i := 0 to FFieldCount-1 do
begin
// field names will be 'Field'+n
if (FFieldLinks[i].IsHidden) then continue;
FFieldLinks[i].AO := nil;
if (FFieldLinks[i].IsExpression) then
if (FFieldLinks[i].Expr <> nil) then
TABSExpression(FFieldLinks[i].Expr).Free;
FFieldLinks[i].IsExpression := False;
FFieldLinks[i].IsAggregate := False;
FFieldLinks[i].Expr := nil;
FFieldLinks[i].Dataset := FResultDataset;
FFieldLinks[i].FieldNo := j;
inc(j);
end; // not result table
end
else
begin
//--- projection is set
if (FIsRootAO) then
for i := 0 to FResultFieldsOrder.ItemCount-1 do
begin
j := FResultFieldsOrder.Items[i];
if (FFieldLinks[j].IsHidden) then
raise EABSException.Create(10314,ErrorLCannotAccessHiddenField,
[FTableName,FFieldLinks[j].FieldName,FFieldLinks[j].DisplayName,j]);
FFieldLinks[j].AO := nil;
if (FFieldLinks[j].IsExpression) then
if (FFieldLinks[j].Expr <> nil) then
TABSExpression(FFieldLinks[j].Expr).Free;
FFieldLinks[j].IsExpression := False;
FFieldLinks[j].IsAggregate := False;
FFieldLinks[j].Expr := nil;
FFieldLinks[j].Dataset := FResultDataset;
FFieldLinks[j].FieldNo := i;
end
else
begin
j := 0;
for i := 0 to FFieldCount-1 do
if (not FFieldLinks[i].IsHidden) then
begin
FFieldLinks[i].AO := nil;
if (FFieldLinks[i].IsExpression) then
if (FFieldLinks[i].Expr <> nil) then
TABSExpression(FFieldLinks[i].Expr).Free;
FFieldLinks[i].IsExpression := False;
FFieldLinks[i].IsAggregate := False;
FFieldLinks[i].Expr := nil;
FFieldLinks[i].Dataset := FResultDataset;
FFieldLinks[i].FieldNo := j;
Inc(j);
end;
end;
end; // result table
FIsMaterialized := True;
//---------------------- destroy child operations -----------------------------
if (FIsAOGroupBy) then
if (TABSAOGroupBy(Self).FTempDataset <> nil) then
begin
TABSAOGroupBy(Self).FTempDataset.Free;
TABSAOGroupBy(Self).FTempDataset := nil;
end;
if (FLeftAO <> nil) then
FLeftAO.Free;
if (FRightAO <> nil) then
FRightAO.Free;
FRightAO := nil;
FLeftAO := nil;
end; // FinalizeMaterialize
//------------------------------------------------------------------------------
// materializes AO
//------------------------------------------------------------------------------
procedure TABSAO.DoMaterialize;
var FieldList,AliasList: TStringList;
begin
if (not FIsMaterialized) then
begin
FieldList := TStringList.Create;
AliasList := TStringList.Create;
try
CreateTableForMaterialize(FieldList,AliasList);
FillTableForMaterialize;
FinalizeMaterialize(FieldList,AliasList);
finally
FieldList.Free;
AliasList.Free;
end;
end;
end; // DoMaterialize
//------------------------------------------------------------------------------
// destroy
//------------------------------------------------------------------------------
destructor TABSAO.Destroy;
var
i: integer;
begin
if (FIsAOTable) then
if (FIsLocked) then
if (ResultDataset.Active) then
TABSTable(ResultDataset).Handle.UnlockTable(ltS, True);
for i := 0 to Length(FFieldLinks)-1 do
if (FFieldLinks[i].IsExpression) then
if (FFieldLinks[i].Expr <> nil) then
TABSExpression(FFieldLinks[i].Expr).Free;
FFieldLinks := nil;
if (FResultDataset <> nil) then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -