DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
JoinedTable.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 
21 using Deveel.Data.Index;
22 
23 namespace Deveel.Data.Sql.Tables {
24  abstract class JoinedTable : Table {
25  private ITable[] referenceList;
26  private ColumnIndex[] indexes;
27 
28  // These two arrays are lookup tables created in the constructor. They allow
29  // for quick resolution of where a given column should be 'routed' to in
30  // the ancestors.
31 
32  private int[] columnTable;
33  private int[] columnFilter;
34 
36 
37  private byte rootsLocked;
38 
39  public JoinedTable(IEnumerable<ITable> tables) {
40  SortColumn = -1;
41  Init(tables);
42  }
43 
44  public JoinedTable(ITable table)
45  : this(new[] {table}) {
46  }
47 
48  protected ColumnIndex[] ColumnIndices {
49  get { return indexes; }
50  }
51 
52  protected int[] ColumnTable {
53  get { return columnTable; }
54  }
55 
56  protected int[] ColumnFilter {
57  get { return columnFilter; }
58  }
59 
60  protected virtual void Init(IEnumerable<ITable> tables) {
61  var tablesArray = tables.ToArray();
62  referenceList = tablesArray;
63 
64  int colCount = ColumnCount;
65  indexes = new ColumnIndex[colCount];
66 
67  vtTableInfo = new TableInfo(new ObjectName("#VIRTUAL TABLE#"));
68 
69  // Generate look up tables for column_table and column_filter information
70 
71  columnTable = new int[colCount];
72  columnFilter = new int[colCount];
73 
74  int index = 0;
75  for (int i = 0; i < referenceList.Length; ++i) {
76  var curTable = referenceList[i];
77  var curTableInfo = curTable.TableInfo;
78  int refColCount = curTable.ColumnCount();
79 
80  // For each column
81  for (int n = 0; n < refColCount; ++n) {
82  columnFilter[index] = n;
83  columnTable[index] = i;
84  ++index;
85 
86  // Add this column to the data table info of this table.
87  var columnInfo = curTableInfo[n];
88  var newColumnInfo = new ColumnInfo(columnInfo.ColumnName, columnInfo.ColumnType) {
89  DefaultExpression = columnInfo.DefaultExpression,
90  IsNotNull = columnInfo.IsNotNull,
91  IndexType = columnInfo.IndexType
92  };
93 
94  vtTableInfo.AddColumnSafe(newColumnInfo);
95  }
96  }
97 
98  vtTableInfo = vtTableInfo.AsReadOnly();
99  }
100 
101  protected override int ColumnCount {
102  get {
103  int columnCountSum = 0;
104  for (int i = 0; i < referenceList.Length; ++i) {
105  columnCountSum += referenceList[i].ColumnCount();
106  }
107  return columnCountSum;
108  }
109  }
110 
111  public override IContext Context {
112  get { return referenceList[0].Context; }
113  }
114 
115  public override TableInfo TableInfo {
116  get { return vtTableInfo; }
117  }
118 
119  protected ITable[] ReferenceTables {
120  get { return referenceList; }
121  }
122 
123  public int SortColumn { get; set; }
124 
125  public override void Lock() {
126  // For each table, recurse.
127  rootsLocked++;
128  for (int i = 0; i < referenceList.Length; ++i) {
129  referenceList[i].Lock();
130  }
131  }
132 
133  public override void Release() {
134  // For each table, recurse.
135  rootsLocked--;
136  for (int i = 0; i < referenceList.Length; ++i) {
137  referenceList[i].Release();
138  }
139  }
140 
141  private IList<int> CalculateRowReferenceList() {
142  int size = RowCount;
143  List<int> allList = new List<int>(size);
144  for (int i = 0; i < size; ++i) {
145  allList.Add(i);
146  }
147  return allList;
148  }
149 
150  protected override int IndexOfColumn(ObjectName columnName) {
151  int colIndex = 0;
152  for (int i = 0; i < referenceList.Length; ++i) {
153  int col = referenceList[i].FindColumn(columnName);
154  if (col != -1)
155  return col + colIndex;
156 
157  colIndex += referenceList[i].ColumnCount();
158  }
159  return -1;
160  }
161 
162  protected override RawTableInfo GetRawTableInfo(RawTableInfo rootInfo) {
163  var allList = new List<int>();
164  int size = RowCount;
165  for (int i = 0; i < size; ++i) {
166  allList.Add(i);
167  }
168 
169  return GetRawTableInfo(rootInfo, allList);
170  }
171 
172  private RawTableInfo GetRawTableInfo(RawTableInfo info, IEnumerable<int> rows) {
173  if (this is IRootTable) {
174  info.Add((IRootTable)this, CalculateRowReferenceList());
175  } else {
176  for (int i = 0; i < referenceList.Length; ++i) {
177 
178  IEnumerable<int> newRowSet = new List<int>(rows);
179 
180  // Resolve the rows into the parents indices.
181  newRowSet = ResolveRowsForTable(newRowSet, i);
182 
183  var table = referenceList[i];
184  if (table is IRootTable) {
185  info.Add((IRootTable)table, newRowSet.ToArray());
186  } else if (table is JoinedTable) {
187  ((JoinedTable)table).GetRawTableInfo(info, newRowSet);
188  }
189  }
190  }
191 
192  return info;
193  }
194 
195  protected override ObjectName GetResolvedColumnName(int column) {
196  var parentTable = referenceList[columnTable[column]];
197  return parentTable.GetResolvedColumnName(columnFilter[column]);
198  }
199 
200  public override DataObject GetValue(long rowNumber, int columnOffset) {
201  int tableNum = columnTable[columnOffset];
202  var parentTable = referenceList[tableNum];
203  rowNumber = ResolveRowForTable((int)rowNumber, tableNum);
204  return parentTable.GetValue(rowNumber, columnFilter[columnOffset]);
205  }
206 
207  public override IEnumerator<Row> GetEnumerator() {
208  return new SimpleRowEnumerator(this);
209  }
210 
211  protected override ColumnIndex GetIndex(int column, int originalColumn, ITable table) {
212  // First check if the given SelectableScheme is in the column_scheme array
213  var scheme = indexes[column];
214  if (scheme != null) {
215  if (table == this)
216  return scheme;
217 
218  return scheme.GetSubset(table, originalColumn);
219  }
220 
221  // If it isn't then we need to calculate it
222  ColumnIndex index;
223 
224  // Optimization: The table may be naturally ordered by a column. If it
225  // is we don't try to generate an ordered set.
226  if (SortColumn != -1 &&
227  SortColumn == column) {
228  var isop = new InsertSearchIndex(this, column, CalculateRowReferenceList());
229  isop.RecordUid = false;
230  index = isop;
231  indexes[column] = index;
232  if (table != this) {
233  index = index.GetSubset(table, originalColumn);
234  }
235 
236  } else {
237  // Otherwise we must generate the ordered set from the information in
238  // a parent index.
239  var parentTable = referenceList[columnTable[column]];
240  index = parentTable.GetIndex(columnFilter[column], originalColumn, table);
241  if (table == this) {
242  indexes[column] = index;
243  }
244  }
245 
246  return index;
247  }
248 
249  protected override IEnumerable<int> ResolveRows(int column, IEnumerable<int> rowSet, ITable ancestor) {
250  if (ancestor == this)
251  return new int[0];
252 
253  int tableNum = columnTable[column];
254  var parentTable = referenceList[tableNum];
255 
256  // Resolve the rows into the parents indices
257  var rows = ResolveRowsForTable(rowSet, tableNum);
258 
259  return parentTable.ResolveRows(columnFilter[column], rows, ancestor);
260  }
261 
262  protected abstract IEnumerable<int> ResolveRowsForTable(IEnumerable<int> rowSet, int tableNum);
263 
264  protected int ResolveRowForTable(int rowNumber, int tableNum) {
265  return ResolveRowsForTable(new[] {rowNumber}, tableNum).First();
266  }
267  }
268 }
Defines the metadata properties of a column within a table of a database.
Definition: ColumnInfo.cs:36
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
override IEnumerator< Row > GetEnumerator()
Definition: JoinedTable.cs:207
void AddColumnSafe(ColumnInfo column)
Definition: TableInfo.cs:203
override IEnumerable< int > ResolveRows(int column, IEnumerable< int > rowSet, ITable ancestor)
Definition: JoinedTable.cs:249
override DataObject GetValue(long rowNumber, int columnOffset)
Gets a single cell within the table that is located at the given column offset and row...
Definition: JoinedTable.cs:200
Describes the name of an object within a database.
Definition: ObjectName.cs:44
JoinedTable(IEnumerable< ITable > tables)
Definition: JoinedTable.cs:39
IList< int > CalculateRowReferenceList()
Definition: JoinedTable.cs:141
override ColumnIndex GetIndex(int column, int originalColumn, ITable table)
Definition: JoinedTable.cs:211
TableInfo AsReadOnly()
Creates a new instance of TableInfo as an immutable copy of this table metadata.
Definition: TableInfo.cs:342
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
TableInfo TableInfo
Gets the metadata information of the table, used to resolve the column sources.
Definition: ITable.cs:47
SqlExpression DefaultExpression
Gets or sets a SqlExpression used as a DEFAULT when a constraint for the column is to SET DEFAULT...
Definition: ColumnInfo.cs:151
void Add(IRootTable table, IList< int > rowSet)
Definition: RawTableInfo.cs:34
RawTableInfo GetRawTableInfo(RawTableInfo info, IEnumerable< int > rows)
Definition: JoinedTable.cs:172
override RawTableInfo GetRawTableInfo(RawTableInfo rootInfo)
Definition: JoinedTable.cs:162
virtual void Init(IEnumerable< ITable > tables)
Definition: JoinedTable.cs:60
int ColumnCount
Gets a count of the columns defined by this object.
Definition: TableInfo.cs:159
override ObjectName GetResolvedColumnName(int column)
Definition: JoinedTable.cs:195
override int IndexOfColumn(ObjectName columnName)
Definition: JoinedTable.cs:150
Object used to represent a column in the ORDER BY clauses of a select statement.
Definition: SortColumn.cs:26
Defines the metadata properties of a table existing within a database.
Definition: TableInfo.cs:41
int ResolveRowForTable(int rowNumber, int tableNum)
Definition: JoinedTable.cs:264
virtual ColumnIndex GetSubset(ITable subsetTable, int subsetColumn)
Definition: ColumnIndex.cs:263
Interface that is implemented by all root tables.
Definition: IRootTable.cs:33