1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
| ///////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2015 by Charta Software B.V. //
// All rights reserved //
// //
// Version: 1.7.0.83525 //
// Web site: https://pascal.chartasoftware.com/ //
// //
// This code and information are provided "as is" without warranty of //
// any kind. Dissemination of this information or reproduction of //
// this material is strictly forbidden unless prior written permission //
// is obtained from Charta Software B.V.. //
// //
///////////////////////////////////////////////////////////////////////////
unit Sql.Statement.ResultSet.Union;
interface
uses
Collection.List,
Integer._32,
Sql.Statement.ResultSet,
Sql.Statement.ResultSet.Select,
Table.Row.Ordering.Column;
type
TSqlUnion = class(TSqlResultSetStatement)
protected
function GetColumns(): TSqlResultSetColumnList; override;
public
DuplicateMode: TSqlDuplicateMode;
Statements: TList<TSqlSelect>;
constructor Create(DuplicateMode: TSqlDuplicateMode); reintroduce; virtual;
destructor Destroy(); override;
function CopyResultSetStatement(): TSqlResultSetStatement; override;
function CopyUnion(): TSqlUnion;
procedure AddSortColumn(Index: TInteger32; Order: TSortOrder = TSortOrder.Ascending);
end;
implementation
uses
Object_.List,
Object_.Reference.Counter,
Sql.Literal;
{ TSqlUnion }
procedure TSqlUnion.AddSortColumn(Index: TInteger32; Order: TSortOrder = TSortOrder.Ascending);
begin
// TODO: We should find a proper way to configure the ORDER BY of a UNION. Currently we use the column position.
// However, the column position is deprecated and instead we should reference the alias of the columns.
// Currently we cannot reference a column alias without qualifying it with a table identifier. Probably we
// should be able to let TSqlUnion have explicit columns that can be referenced.
OrderBy.Add(TSqlOrderByExpression.Create(TSqlLiteralInteger.Create(1), Order));
end;
function TSqlUnion.CopyResultSetStatement(): TSqlResultSetStatement;
begin
Result := CopyUnion();
end;
function TSqlUnion.CopyUnion(): TSqlUnion;
var
Statement: TSqlSelect;
OrderByExpression: TSqlOrderByExpression;
begin
Result := TSqlUnion.Create(DuplicateMode);
for Statement in Statements do
Result.Statements.Add(Statement.CopySelect());
for OrderByExpression in OrderBy do
Result.OrderBy.Add(OrderByExpression.CopyOrderByExpression());
Result.Limit.AssignFrom(Limit);
end;
constructor TSqlUnion.Create(DuplicateMode: TSqlDuplicateMode);
begin
inherited Create();
Self.DuplicateMode := DuplicateMode;
Statements := TObjectList<TSqlSelect>.Create();
Statements.ElementManager := TReferenceCounter<TSqlSelect>.Create();
end;
destructor TSqlUnion.Destroy();
begin
Statements.Free();
inherited Destroy();
end;
function TSqlUnion.GetColumns(): TSqlResultSetColumnList;
begin
Result := Statements[0].Columns;
end;
end.
|