DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
NaturallyJoinedTable.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 namespace Deveel.Data.Sql.Tables {
23  // The row counts of the left and right tables.
24  private readonly int leftRowCount, rightRowCount;
25 
26  // The lookup row set for the left and right tables. Basically, these point
27  // to each row in either the left or right tables.
28  private readonly IList<int> leftSet, rightSet;
29  private readonly bool leftIsSimpleEnum, rightIsSimpleEnum;
30 
31  public NaturallyJoinedTable(ITable left, ITable right)
32  : base(new[] {left, right}) {
33  leftRowCount = left.RowCount;
34  rightRowCount = right.RowCount;
35 
36  // Build lookup tables for the rows in the parent tables if necessary
37  // (usually it's not necessary).
38 
39  // If the left or right tables are simple enumerations, we can optimize
40  // our access procedure,
41  leftIsSimpleEnum = (left.GetEnumerator() is SimpleRowEnumerator);
42  rightIsSimpleEnum = (right.GetEnumerator() is SimpleRowEnumerator);
43 
44  leftSet = !leftIsSimpleEnum ? left.Select(x => x.RowId.RowNumber).ToList() : null;
45  rightSet = !rightIsSimpleEnum ? right.Select(x => x.RowId.RowNumber).ToList() : null;
46  }
47 
48  public override int RowCount {
49  get {
50  // Natural join row count is (left table row count * right table row count)
51  return leftRowCount * rightRowCount;
52  }
53  }
54 
55  private int GetLeftRowIndex(int rowIndex) {
56  if (leftIsSimpleEnum)
57  return rowIndex;
58 
59  return leftSet[rowIndex];
60  }
61 
62  private int GetRightRowIndex(int rowIndex) {
63  if (rightIsSimpleEnum)
64  return rowIndex;
65 
66  return rightSet[rowIndex];
67  }
68 
69  protected override IEnumerable<int> ResolveRowsForTable(IEnumerable<int> rowSet, int tableNum) {
70  var rowList = rowSet.ToList();
71  bool pickRightTable = (tableNum == 1);
72  for (int n = rowList.Count - 1; n >= 0; --n) {
73  int aa = rowList[n];
74  // Reverse map row index to parent domain
75  int parentRow;
76  if (pickRightTable) {
77  parentRow = GetRightRowIndex(aa % rightRowCount);
78  } else {
79  parentRow = GetLeftRowIndex(aa / rightRowCount);
80  }
81  rowList[n] = parentRow;
82  }
83 
84  return rowList.ToArray();
85  }
86  }
87 }
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
override IEnumerable< int > ResolveRowsForTable(IEnumerable< int > rowSet, int tableNum)