DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
Static Public Member Functions | Static Private Member Functions | List of all members
Deveel.Data.Sql.Tables.TableQueryExtensions Class Reference

Provides a set of extension methods to ITable and IMutableTable objects. More...

Static Public Member Functions

static DataObject GetValue (this ITable table, int rowIndex, ObjectName columnName)
 
static DataObject GetValue (this ITable table, int rowIndex, string columnName)
 
static DataObject GetLastValue (this ITable table, int columnOffset)
 
static DataObject GetLastValue (this ITable table, string columnName)
 
static DataObject[] GetLastValues (this ITable table, int[] columnOffsets)
 
static DataObject GetFirstValue (this ITable table, int columnOffset)
 
static DataObject GetFirstValue (this ITable table, string columnName)
 
static DataObject[] GetFirstValues (this ITable table, int[] columnOffsets)
 
static DataObject GetSingleValue (this ITable table, int columnOffset)
 
static DataObject GetSingleValue (this ITable table, string columnName)
 
static DataObject[] GetSingleValues (this ITable table, int[] columnOffsets)
 
static Row GetRow (this ITable table, int rowNumber)
 
static IEnumerable< int > FindKeys (this ITable table, int[] columnOffsets, DataObject[] keyValue)
 
static int IndexOfColumn (this ITable table, string columnName)
 
static int IndexOfColumn (this ITable table, ObjectName columnName)
 
static IEnumerable< int > SelectRowsEqual (this ITable table, int columnIndex, DataObject value)
 
static IEnumerable< int > SelectRowsEqual (this ITable table, string columnName, DataObject value)
 
static IEnumerable< int > SelectNotEqual (this ITable table, int columnOffset, DataObject value)
 
static IEnumerable< int > SelectNotEqual (this ITable table, int columnOffset, ISqlObject value)
 
static IEnumerable< int > SelectRowsEqual (this ITable table, int columnIndex1, DataObject value1, int columnIndex2, DataObject value2)
 
static IEnumerable< int > SelectRowsRange (this ITable table, int column, IndexRange[] ranges)
 
static IEnumerable< int > SelectRowsGreater (this ITable table, int columnOffset, DataObject value)
 
static IEnumerable< int > SelectRowsGreater (this ITable table, int columnOffset, ISqlObject value)
 
static IEnumerable< int > SelectRowsGreaterOrEqual (this ITable table, int columnOffset, DataObject value)
 
static IEnumerable< int > SelectRowsGreaterOrEqual (this ITable table, int columnOffset, ISqlObject value)
 
static IEnumerable< int > SelecRowsLess (this ITable table, int columnOffset, DataObject value)
 
static IEnumerable< int > SelecRowsLess (this ITable table, int columnOffset, ISqlObject value)
 
static IEnumerable< int > SelectRowsLessOrEqual (this ITable table, int columnOffset, DataObject value)
 
static IEnumerable< int > SelectRowsLessOrEqual (this ITable table, int columnOffset, ISqlObject value)
 
static IEnumerable< int > SelectAllRows (this ITable table, int columnOffset)
 
static IEnumerable< int > SelectAllRows (this ITable table)
 
static IEnumerable< int > SelectLast (this ITable table, int columnOffset)
 
static IEnumerable< int > SelectFirst (this ITable table, int columnOffset)
 
static IEnumerable< int > SelectRows (this ITable table, IVariableResolver resolver, IRequest context, SqlBinaryExpression expression)
 
static IEnumerable< int > SelectRows (this ITable table, int[] columnOffsets, SqlExpressionType op, DataObject[] values)
 
static IEnumerable< int > SelectRowsBetween (this ITable table, int column, DataObject minCell, DataObject maxCell)
 
static IEnumerable< int > SelectRows (this ITable table, int column, SqlExpressionType op, DataObject value)
 
static IEnumerable< int > Search (this ITable table, int column, string pattern)
 
static IEnumerable< int > Search (this ITable table, int column, string pattern, char escapeChar)
 
static ITable SelectEqual (this ITable table, int columnIndex, DataObject value)
 
static ITable SelectEqual (this ITable table, string columnName, DataObject value)
 
static ITable SelectAll (this ITable table, int columnOffset)
 
static ITable Select (this ITable table, IRequest context, SqlExpression expression)
 
static ITable SimpleSelect (this ITable table, IRequest context, ObjectName columnName, SqlExpressionType op, SqlExpression exp)
 
static ITable ExhaustiveSelect (this ITable table, IRequest context, SqlExpression expression)
 
static IEnumerable< int > SelectFromPattern (this ITable table, int column, SqlExpressionType op, DataObject ob)
 
static ITable EmptySelect (this ITable table)
 
static ITable DistinctBy (this ITable table, int[] columns)
 
static ITable DistinctBy (this ITable table, ObjectName[] columnNames)
 
static ITable SelectRange (this ITable thisTable, ObjectName columnName, IndexRange[] ranges)
 
static bool AllRowsMatchColumnValue (this ITable table, int columnOffset, SqlExpressionType op, DataObject value)
 
static ITable SelectAnyAllNonCorrelated (this ITable table, ObjectName[] leftColumns, SqlExpressionType op, ITable rightTable)
 
static ITable Union (this ITable thisTable, ITable otherTable)
 
static IEnumerable< int > SelectRowsIn (this ITable table, ITable other, int column1, int column2)
 This implements the in command. More...
 
static IEnumerable< int > SelectRowsIn (this ITable table, ITable other, int[] t1Cols, int[] t2Cols)
 A multi-column version of IN. More...
 
static IEnumerable< int > SelectRowsNotIn (this ITable table, ITable other, int col1, int col2)
 This implements the not in command. More...
 
static IEnumerable< int > SelectRowsNotIn (this ITable table, ITable other, int[] t1Cols, int[] t2Cols)
 A multi-column version of NOT IN. More...
 
static ITable NotIn (this ITable table, ITable otherTable, int[] tableColumns, int[] otherColumns)
 
static ITable Composite (this ITable table, ITable other, CompositeFunction function, bool all)
 
static ITable Execept (this ITable table, ITable other, bool all)
 
static ITable Intersect (this ITable table, ITable other, bool all)
 
static ITable Join (this ITable table, ITable otherTable, bool quick)
 
static ITable NaturalJoin (this ITable table, ITable otherTable)
 
static ITable Join (this ITable table, IRequest context, ITable other, ObjectName columnName, SqlExpressionType operatorType, SqlExpression expression)
 
static ITable SimpleJoin (this ITable thisTable, IRequest context, ITable other, SqlBinaryExpression binary)
 
static ITable OuterJoin (this ITable table, ITable rightTable)
 
static ITable EquiJoin (this ITable table, IRequest context, ITable other, ObjectName[] leftColumns, ObjectName[] rightColumns)
 
static IEnumerable< int > OrderRowsByColumns (this ITable table, int[] columns)
 
static ITable OrderBy (this ITable table, int[] columns)
 
static ITable OrderBy (this ITable table, int columnIndex, bool ascending)
 
static ITable OrderBy (this ITable table, ObjectName columnName, bool ascending)
 
static ITable OrderBy (this ITable table, ObjectName[] columnNames, bool[] ascending)
 
static ITable OrderBy (this ITable table, string columnName, bool ascending)
 
static ITable Subset (this ITable table, ObjectName[] columnNames, ObjectName[] aliases)
 
static bool Exists (this ITable table, int columnOffset, DataObject value)
 
static bool Exists (this ITable table, int columnOffset1, DataObject value1, int columnOffset2, DataObject value2)
 
static ITable ColumnMerge (this ITable table, ITable other)
 
static Dictionary< string, ISqlObjectToDictionary (this ITable table)
 

Static Private Member Functions

static DataObject MakeObject (this ITable table, int columnOffset, ISqlObject value)
 
static ITable AsVirtual (this ITable table, Func< IEnumerable< int >> selector)
 

Detailed Description

Provides a set of extension methods to ITable and IMutableTable objects.

Definition at line 34 of file TableQueryExtensions.cs.

Member Function Documentation

static bool Deveel.Data.Sql.Tables.TableQueryExtensions.AllRowsMatchColumnValue ( this ITable  table,
int  columnOffset,
SqlExpressionType  op,
DataObject  value 
)
inlinestatic

Definition at line 747 of file TableQueryExtensions.cs.

747  {
748  var rows = table.SelectRows(columnOffset, op, value);
749  return rows.Count() == table.RowCount;
750  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.AsVirtual ( this ITable  table,
Func< IEnumerable< int >>  selector 
)
inlinestaticprivate

Definition at line 1380 of file TableQueryExtensions.cs.

1380  {
1381  return new VirtualTable(table, selector().ToArray());
1382  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.ColumnMerge ( this ITable  table,
ITable  other 
)
inlinestatic

Definition at line 1384 of file TableQueryExtensions.cs.

1384  {
1385  if (table.RowCount != other.RowCount)
1386  throw new InvalidOperationException("Tables have different row counts.");
1387 
1388  // Create the new VirtualTable with the joined tables.
1389 
1390  List<int> allRowSet = new List<int>();
1391  int rcount = table.RowCount;
1392  for (int i = 0; i < rcount; ++i) {
1393  allRowSet.Add(i);
1394  }
1395 
1396  var tabs = new[] { table, other };
1397  var rowSets = new IList<int>[] { allRowSet, allRowSet };
1398 
1399  return new VirtualTable(tabs, rowSets);
1400  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Composite ( this ITable  table,
ITable  other,
CompositeFunction  function,
bool  all 
)
inlinestatic

Definition at line 1067 of file TableQueryExtensions.cs.

1067  {
1068  return new CompositeTable(table, new[] { table, other }, function, all);
1069  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.DistinctBy ( this ITable  table,
int[]  columns 
)
inlinestatic

Definition at line 662 of file TableQueryExtensions.cs.

662  {
663  List<int> resultList = new List<int>();
664  var rowList = table.OrderRowsByColumns(columns).ToList();
665 
666  int rowCount = rowList.Count;
667  int previousRow = -1;
668  for (int i = 0; i < rowCount; ++i) {
669  int rowIndex = rowList[i];
670 
671  if (previousRow != -1) {
672 
673  bool equal = true;
674  // Compare cell in column in this row with previous row.
675  for (int n = 0; n < columns.Length && equal; ++n) {
676  var c1 = table.GetValue(columns[n], rowIndex);
677  var c2 = table.GetValue(columns[n], previousRow);
678  equal = (c1.CompareTo(c2) == 0);
679  }
680 
681  if (!equal) {
682  resultList.Add(rowIndex);
683  }
684  } else {
685  resultList.Add(rowIndex);
686  }
687 
688  previousRow = rowIndex;
689  }
690 
691  // Return the new table with distinct rows only.
692  return new VirtualTable(table, resultList);
693  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.DistinctBy ( this ITable  table,
ObjectName[]  columnNames 
)
inlinestatic

Definition at line 695 of file TableQueryExtensions.cs.

695  {
696  var mapSize = columnNames.Length;
697  var map = new int[mapSize];
698  for (int i = 0; i < mapSize; i++) {
699  map[i] = table.IndexOfColumn(columnNames[i]);
700  }
701 
702  return table.DistinctBy(map);
703  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.EmptySelect ( this ITable  table)
inlinestatic

Definition at line 655 of file TableQueryExtensions.cs.

655  {
656  if (table.RowCount == 0)
657  return table;
658 
659  return new VirtualTable(table, new int[0]);
660  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.EquiJoin ( this ITable  table,
IRequest  context,
ITable  other,
ObjectName[]  leftColumns,
ObjectName[]  rightColumns 
)
inlinestatic

Definition at line 1259 of file TableQueryExtensions.cs.

1259  {
1260  // TODO: This needs to migrate to a better implementation that
1261  // exploits multi-column indexes if one is defined that can be used.
1262 
1263  var firstLeft = SqlExpression.Reference(leftColumns[0]);
1264  var firstRight = SqlExpression.Reference(rightColumns[0]);
1265  var onExpression = SqlExpression.Equal(firstLeft, firstRight);
1266 
1267  var result = table.SimpleJoin(context, other, onExpression);
1268 
1269  int sz = leftColumns.Length;
1270 
1271  // If there are columns left to equi-join, we resolve the rest with a
1272  // single exhaustive select of the form,
1273  // ( table1.col2 = table2.col2 AND table1.col3 = table2.col3 AND ... )
1274  if (sz > 1) {
1275  // Form the expression
1276  SqlExpression restExpression = null;
1277  for (int i = 1; i < sz; ++i) {
1278  var left = SqlExpression.Reference(leftColumns[i]);
1279  var right = SqlExpression.Reference(rightColumns[i]);
1280  var equalExp = SqlExpression.And(left, right);
1281 
1282  if (restExpression == null) {
1283  restExpression = equalExp;
1284  } else {
1285  restExpression = SqlExpression.And(restExpression, equalExp);
1286  }
1287  }
1288 
1289  result = result.ExhaustiveSelect(context, restExpression);
1290  }
1291 
1292  return result;
1293  }
static SqlBinaryExpression And(SqlExpression left, SqlExpression right)
static SqlBinaryExpression Equal(SqlExpression left, SqlExpression right)
static SqlReferenceExpression Reference(ObjectName objectName)
Defines the base class for instances that represent SQL expression tree nodes.
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Execept ( this ITable  table,
ITable  other,
bool  all 
)
inlinestatic

Definition at line 1071 of file TableQueryExtensions.cs.

1071  {
1072  return table.Composite(other, CompositeFunction.Except, all);
1073  }
CompositeFunction
The kind of composite function in a CompositeTable.
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.ExhaustiveSelect ( this ITable  table,
IRequest  context,
SqlExpression  expression 
)
inlinestatic

Definition at line 586 of file TableQueryExtensions.cs.

586  {
587  var result = table;
588 
589  // Exit early if there's nothing in the table to select from
590  int rowCount = table.RowCount;
591  if (rowCount > 0) {
592  var tableResolver = table.GetVariableResolver();
593  List<int> selectedSet = new List<int>(rowCount);
594 
595  foreach (var row in table) {
596  int rowIndex = row.RowId.RowNumber;
597 
598  var rowResolver = tableResolver.ForRow(rowIndex);
599 
600  // Resolve expression into a constant.
601  var exp = expression.Evaluate(context, rowResolver);
602  if (exp.ExpressionType != SqlExpressionType.Constant)
603  throw new NotSupportedException();
604 
605  var value = ((SqlConstantExpression) exp).Value;
606  // If resolved to true then include in the selected set.
607  if (!value.IsNull && value.Type is BooleanType &&
608  value == true) {
609  selectedSet.Add(rowIndex);
610  }
611  }
612 
613  result = new VirtualTable(table, selectedSet); ;
614  }
615 
616  return result;
617  }
SqlExpressionType
All the possible type of SqlExpression supported
virtual SqlExpression Evaluate(EvaluateContext context)
When overridden by a derived class, this method evaluates the expression within the provided context...
An expression that holds a constant value.
static bool Deveel.Data.Sql.Tables.TableQueryExtensions.Exists ( this ITable  table,
int  columnOffset,
DataObject  value 
)
inlinestatic

Definition at line 1372 of file TableQueryExtensions.cs.

1372  {
1373  return table.SelectRowsEqual(columnOffset, value).Any();
1374  }
static bool Deveel.Data.Sql.Tables.TableQueryExtensions.Exists ( this ITable  table,
int  columnOffset1,
DataObject  value1,
int  columnOffset2,
DataObject  value2 
)
inlinestatic

Definition at line 1376 of file TableQueryExtensions.cs.

1376  {
1377  return table.SelectRowsEqual(columnOffset1, value1, columnOffset2, value2).Any();
1378  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.FindKeys ( this ITable  table,
int[]  columnOffsets,
DataObject[]  keyValue 
)
inlinestatic

Definition at line 104 of file TableQueryExtensions.cs.

104  {
105  int keySize = keyValue.Length;
106 
107  // Now command table 2 to determine if the key values are present.
108  // Use index scan on first key.
109  var columnIndex = table.GetIndex(columnOffsets[0]);
110  var list = columnIndex.SelectEqual(keyValue[0]).ToList();
111 
112  if (keySize <= 1)
113  return list;
114 
115  // Full scan for the rest of the columns
116  int sz = list.Count;
117 
118  // For each element of the list
119  for (int i = sz - 1; i >= 0; --i) {
120  int rIndex = list[i];
121  // For each key in the column list
122  for (int c = 1; c < keySize; ++c) {
123  int columnOffset = columnOffsets[c];
124  var columnValue = keyValue[c];
125  if (columnValue.CompareTo(table.GetValue(rIndex, columnOffset)) != 0) {
126  // If any values in the key are not equal set this flag to false
127  // and remove the index from the list.
128  list.RemoveAt(i);
129  // Break the for loop
130  break;
131  }
132  }
133  }
134 
135  return list;
136  }
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetFirstValue ( this ITable  table,
int  columnOffset 
)
inlinestatic

Definition at line 61 of file TableQueryExtensions.cs.

61  {
62  var rows = table.SelectFirst(columnOffset).ToList();
63  return rows.Count > 0 ? table.GetValue(rows[0], columnOffset) : null;
64  }
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetFirstValue ( this ITable  table,
string  columnName 
)
inlinestatic

Definition at line 66 of file TableQueryExtensions.cs.

66  {
67  return table.GetFirstValue(table.IndexOfColumn(columnName));
68  }
static DataObject [] Deveel.Data.Sql.Tables.TableQueryExtensions.GetFirstValues ( this ITable  table,
int[]  columnOffsets 
)
inlinestatic

Definition at line 70 of file TableQueryExtensions.cs.

70  {
71  if (columnOffsets.Length > 1)
72  throw new ArgumentException("Multi-column gets not supported.");
73 
74  return new[] {table.GetFirstValue(columnOffsets[0])};
75  }
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetLastValue ( this ITable  table,
int  columnOffset 
)
inlinestatic

Definition at line 45 of file TableQueryExtensions.cs.

45  {
46  var rows = table.SelectLast(columnOffset).ToList();
47  return rows.Count > 0 ? table.GetValue(rows[0], columnOffset) : null;
48  }
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetLastValue ( this ITable  table,
string  columnName 
)
inlinestatic

Definition at line 50 of file TableQueryExtensions.cs.

50  {
51  return table.GetLastValue(table.IndexOfColumn(columnName));
52  }
static DataObject [] Deveel.Data.Sql.Tables.TableQueryExtensions.GetLastValues ( this ITable  table,
int[]  columnOffsets 
)
inlinestatic

Definition at line 54 of file TableQueryExtensions.cs.

54  {
55  if (columnOffsets.Length > 1)
56  throw new ArgumentException("Multi-column gets not supported.");
57 
58  return new[] {table.GetLastValue(columnOffsets[0])};
59  }
static Row Deveel.Data.Sql.Tables.TableQueryExtensions.GetRow ( this ITable  table,
int  rowNumber 
)
inlinestatic

Definition at line 98 of file TableQueryExtensions.cs.

98  {
99  return new Row(table, new RowId(table.TableInfo.Id, rowNumber));
100  }
A single ROW in a database table, that holds tabular data as configured by the table specifications...
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetSingleValue ( this ITable  table,
int  columnOffset 
)
inlinestatic

Definition at line 77 of file TableQueryExtensions.cs.

77  {
78  IList<int> rows = table.SelectFirst(columnOffset).ToList();
79  int sz = rows.Count;
80  return sz == table.RowCount && sz > 0 ? table.GetValue(rows[0], columnOffset) : null;
81  }
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetSingleValue ( this ITable  table,
string  columnName 
)
inlinestatic

Definition at line 83 of file TableQueryExtensions.cs.

83  {
84  return table.GetSingleValue(table.IndexOfColumn(columnName));
85  }
static DataObject [] Deveel.Data.Sql.Tables.TableQueryExtensions.GetSingleValues ( this ITable  table,
int[]  columnOffsets 
)
inlinestatic

Definition at line 87 of file TableQueryExtensions.cs.

87  {
88  if (columnOffsets.Length > 1)
89  throw new ArgumentException("Multi-column gets not supported.");
90 
91  return new[] {table.GetSingleValue(columnOffsets[0])};
92  }
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetValue ( this ITable  table,
int  rowIndex,
ObjectName  columnName 
)
inlinestatic

Definition at line 37 of file TableQueryExtensions.cs.

37  {
38  return table.GetValue(rowIndex, table.IndexOfColumn(columnName));
39  }
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.GetValue ( this ITable  table,
int  rowIndex,
string  columnName 
)
inlinestatic

Definition at line 41 of file TableQueryExtensions.cs.

41  {
42  return table.GetValue(rowIndex, table.ResolveColumnName(columnName));
43  }
static int Deveel.Data.Sql.Tables.TableQueryExtensions.IndexOfColumn ( this ITable  table,
string  columnName 
)
inlinestatic

Definition at line 146 of file TableQueryExtensions.cs.

146  {
147  if (table is IQueryTable)
148  return ((IQueryTable) table).FindColumn(ObjectName.Parse(columnName));
149 
150  return table.TableInfo.IndexOfColumn(columnName);
151  }
static int Deveel.Data.Sql.Tables.TableQueryExtensions.IndexOfColumn ( this ITable  table,
ObjectName  columnName 
)
inlinestatic

Definition at line 153 of file TableQueryExtensions.cs.

153  {
154  if (table is IQueryTable)
155  return ((IQueryTable) table).FindColumn(columnName);
156 
157  if (columnName.Parent != null &&
158  !columnName.Parent.Equals(table.TableInfo.TableName))
159  return -1;
160 
161  return table.TableInfo.IndexOfColumn(columnName);
162  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Intersect ( this ITable  table,
ITable  other,
bool  all 
)
inlinestatic

Definition at line 1075 of file TableQueryExtensions.cs.

1075  {
1076  return table.Composite(other, CompositeFunction.Intersect, all);
1077  }
CompositeFunction
The kind of composite function in a CompositeTable.
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Join ( this ITable  table,
ITable  otherTable,
bool  quick 
)
inlinestatic

Definition at line 1083 of file TableQueryExtensions.cs.

1083  {
1084  ITable outTable;
1085 
1086  if (quick) {
1087  // This implementation doesn't materialize the join
1088  outTable = new NaturallyJoinedTable(table, otherTable);
1089  } else {
1090  var tabs = new [] { table, otherTable};
1091  var rowSets = new IList<int>[2];
1092 
1093  // Optimized trivial case, if either table has zero rows then result of
1094  // join will contain zero rows also.
1095  if (table.RowCount == 0 || otherTable.RowCount == 0) {
1096  rowSets[0] = new List<int>(0);
1097  rowSets[1] = new List<int>(0);
1098  } else {
1099  // The natural join algorithm.
1100  List<int> thisRowSet = new List<int>();
1101  List<int> tableRowSet = new List<int>();
1102 
1103  // Get the set of all rows in the given table.
1104  var tableSelectedSet = otherTable.Select(x => x.RowId.RowNumber).ToList();
1105 
1106  int tableSelectedSetSize = tableSelectedSet.Count;
1107 
1108  // Join with the set of rows in this table.
1109  var e = table.GetEnumerator();
1110  while (e.MoveNext()) {
1111  int rowIndex = e.Current.RowId.RowNumber;
1112  for (int i = 0; i < tableSelectedSetSize; ++i) {
1113  thisRowSet.Add(rowIndex);
1114  }
1115 
1116  tableRowSet.AddRange(tableSelectedSet);
1117  }
1118 
1119  // The row sets we are joining from each table.
1120  rowSets[0] = thisRowSet;
1121  rowSets[1] = tableRowSet;
1122  }
1123 
1124  // Create the new VirtualTable with the joined tables.
1125  outTable = new VirtualTable(tabs, rowSets);
1126  }
1127 
1128  return outTable;
1129  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Join ( this ITable  table,
IRequest  context,
ITable  other,
ObjectName  columnName,
SqlExpressionType  operatorType,
SqlExpression  expression 
)
inlinestatic

Definition at line 1135 of file TableQueryExtensions.cs.

1136  {
1137  var rightExpression = expression;
1138  // If the rightExpression is a simple variable then we have the option
1139  // of optimizing this join by putting the smallest table on the LHS.
1140  var rhsVar = rightExpression.AsReferenceName();
1141  var lhsVar = columnName;
1142  var op = operatorType;
1143 
1144  if (rhsVar != null) {
1145  // We should arrange the expression so the right table is the smallest
1146  // of the sides.
1147  // If the left result is less than the right result
1148 
1149  if (table.RowCount < other.RowCount) {
1150  // Reverse the join
1151  rightExpression = SqlExpression.Reference(lhsVar);
1152  lhsVar = rhsVar;
1153  op = op.Reverse();
1154 
1155  // Reverse the tables.
1156  var t = other;
1157  other = table;
1158  table = t;
1159  }
1160  }
1161 
1162  var joinExp = SqlExpression.Binary(SqlExpression.Reference(lhsVar), op, rightExpression);
1163 
1164  // The join operation.
1165  return table.SimpleJoin(context, other, joinExp);
1166  }
static SqlReferenceExpression Reference(ObjectName objectName)
static SqlBinaryExpression Binary(SqlExpression left, SqlExpressionType expressionType, SqlExpression right)
Defines the base class for instances that represent SQL expression tree nodes.
static DataObject Deveel.Data.Sql.Tables.TableQueryExtensions.MakeObject ( this ITable  table,
int  columnOffset,
ISqlObject  value 
)
inlinestaticprivate

Definition at line 138 of file TableQueryExtensions.cs.

138  {
139  if (columnOffset < 0 || columnOffset >= table.TableInfo.ColumnCount)
140  throw new ArgumentOutOfRangeException("columnOffset");
141 
142  var columnType = table.TableInfo[columnOffset].ColumnType;
143  return new DataObject(columnType, value);
144  }
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.NaturalJoin ( this ITable  table,
ITable  otherTable 
)
inlinestatic

Definition at line 1131 of file TableQueryExtensions.cs.

1131  {
1132  return table.Join(otherTable, true);
1133  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.NotIn ( this ITable  table,
ITable  otherTable,
int[]  tableColumns,
int[]  otherColumns 
)
inlinestatic

Definition at line 1063 of file TableQueryExtensions.cs.

1063  {
1064  return table.AsVirtual(() => SelectRowsNotIn(table, otherTable, tableColumns, otherColumns));
1065  }
static IEnumerable< int > SelectRowsNotIn(this ITable table, ITable other, int col1, int col2)
This implements the not in command.
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.OrderBy ( this ITable  table,
int[]  columns 
)
inlinestatic

Definition at line 1309 of file TableQueryExtensions.cs.

1309  {
1310  // Sort by the column list.
1311  ITable resultTable = table;
1312  for (int i = columns.Length - 1; i >= 0; --i) {
1313  resultTable = resultTable.OrderBy(columns[i], true);
1314  }
1315 
1316  // A nice post condition to check on.
1317  if (resultTable.RowCount != table.RowCount)
1318  throw new InvalidOperationException("The final row count mismatches.");
1319 
1320  return table;
1321  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.OrderBy ( this ITable  table,
int  columnIndex,
bool  ascending 
)
inlinestatic

Definition at line 1323 of file TableQueryExtensions.cs.

1323  {
1324  if (table == null)
1325  return null;
1326 
1327  var rows = table.SelectAllRows(columnIndex);
1328 
1329  // Reverse the list if we are not ascending
1330  if (@ascending == false)
1331  rows = rows.Reverse();
1332 
1333  return new VirtualTable(table, rows.ToArray());
1334  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.OrderBy ( this ITable  table,
ObjectName  columnName,
bool  ascending 
)
inlinestatic

Definition at line 1336 of file TableQueryExtensions.cs.

1336  {
1337  var columnOffset = table.IndexOfColumn(columnName);
1338  if (columnOffset == -1)
1339  throw new ArgumentException(String.Format("Column '{0}' was not found in table.", columnName));
1340 
1341  return table.OrderBy(columnOffset, @ascending);
1342  }
A long string in the system.
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.OrderBy ( this ITable  table,
ObjectName[]  columnNames,
bool[]  ascending 
)
inlinestatic

Definition at line 1344 of file TableQueryExtensions.cs.

1344  {
1345  var result = table;
1346  // Sort the results by the columns in reverse-safe order.
1347  int sz = ascending.Length;
1348  for (int n = sz - 1; n >= 0; --n) {
1349  result = result.OrderBy(columnNames[n], ascending[n]);
1350  }
1351  return result;
1352  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.OrderBy ( this ITable  table,
string  columnName,
bool  ascending 
)
inlinestatic

Definition at line 1354 of file TableQueryExtensions.cs.

1354  {
1355  return table.OrderBy(table.ResolveColumnName(columnName), ascending);
1356  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.OrderRowsByColumns ( this ITable  table,
int[]  columns 
)
inlinestatic

Definition at line 1299 of file TableQueryExtensions.cs.

1299  {
1300  var work = table.OrderBy(columns);
1301  // 'work' is now sorted by the columns,
1302  // Get the rows in this tables domain,
1303  var rowList = work.Select(row => row.RowId.RowNumber);
1304 
1305  return work.ResolveRows(0, rowList, table);
1306  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.OuterJoin ( this ITable  table,
ITable  rightTable 
)
inlinestatic

Definition at line 1218 of file TableQueryExtensions.cs.

1218  {
1219  // Form the row list for right hand table,
1220  var rowList = rightTable.Select(x => x.RowId.RowNumber).ToList();
1221 
1222  int colIndex = rightTable.IndexOfColumn(table.GetResolvedColumnName(0));
1223  rowList = rightTable.ResolveRows(colIndex, rowList, table).ToList();
1224 
1225  // This row set
1226  var thisTableSet = table.Select(x => x.RowId.RowNumber).ToList();
1227 
1228  thisTableSet.Sort();
1229  rowList.Sort();
1230 
1231  // Find all rows that are in 'this table' and not in 'right'
1232  List<int> resultList = new List<int>(96);
1233  int size = thisTableSet.Count;
1234  int rowListIndex = 0;
1235  int rowListSize = rowList.Count;
1236  for (int i = 0; i < size; ++i) {
1237  int thisVal = thisTableSet[i];
1238  if (rowListIndex < rowListSize) {
1239  int inVal = rowList[rowListIndex];
1240  if (thisVal < inVal) {
1241  resultList.Add(thisVal);
1242  } else if (thisVal == inVal) {
1243  while (rowListIndex < rowListSize &&
1244  rowList[rowListIndex] == inVal) {
1245  ++rowListIndex;
1246  }
1247  } else {
1248  throw new InvalidOperationException("'this_val' > 'in_val'");
1249  }
1250  } else {
1251  resultList.Add(thisVal);
1252  }
1253  }
1254 
1255  // Return the new VirtualTable
1256  return new VirtualTable(table, resultList);
1257  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.Search ( this ITable  table,
int  column,
string  pattern 
)
inlinestatic

Definition at line 325 of file TableQueryExtensions.cs.

325  {
326  return table.Search(column, pattern, '\\');
327  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.Search ( this ITable  table,
int  column,
string  pattern,
char  escapeChar 
)
inlinestatic

Definition at line 329 of file TableQueryExtensions.cs.

329  {
330  var colType = table.TableInfo[column].ColumnType;
331 
332  // If the column type is not a string type then report an error.
333  if (!(colType is StringType))
334  throw new InvalidOperationException("Unable to perform a pattern search on a non-String type column.");
335 
336  // First handle the case that the column has an index that supports text search
337  var index = table.GetIndex(column);
338  if (index != null && index.HandlesTextSearch)
339  return index.SelectLike(DataObject.String(pattern));
340 
341  var colStringType = (StringType)colType;
342 
343  // ---------- Pre Search ----------
344 
345  // First perform a 'pre-search' on the head of the pattern. Note that
346  // there may be no head in which case the entire column is searched which
347  // has more potential to be expensive than if there is a head.
348 
349  StringBuilder prePattern = new StringBuilder();
350  int i = 0;
351  bool finished = i >= pattern.Length;
352  bool lastIsEscape = false;
353 
354  while (!finished) {
355  char c = pattern[i];
356  if (lastIsEscape) {
357  lastIsEscape = true;
358  prePattern.Append(c);
359  } else if (c == escapeChar) {
360  lastIsEscape = true;
361  } else if (!PatternSearch.IsWildCard(c)) {
362  prePattern.Append(c);
363 
364  ++i;
365  if (i >= pattern.Length) {
366  finished = true;
367  }
368 
369  } else {
370  finished = true;
371  }
372  }
373 
374  // This is set with the remaining search.
375  string postPattern;
376 
377  // This is our initial search row set. In the second stage, rows are
378  // eliminated from this vector.
379  IEnumerable<int> searchCase;
380 
381  if (i >= pattern.Length) {
382  // If the pattern has no 'wildcards' then just perform an EQUALS
383  // operation on the column and return the results.
384 
385  var cell = new DataObject(colType, new SqlString(pattern));
386  return SelectRows(table, column, SqlExpressionType.Equal, cell);
387  }
388 
389  if (prePattern.Length == 0 ||
390  colStringType.Locale != null) {
391 
392  // No pre-pattern easy search :-(. This is either because there is no
393  // pre pattern (it starts with a wild-card) or the locale of the string
394  // is non-lexicographical. In either case, we need to select all from
395  // the column and brute force the search space.
396 
397  searchCase = table.SelectAllRows(column);
398  postPattern = pattern;
399  } else {
400 
401  // Criteria met: There is a pre_pattern, and the column locale is
402  // lexicographical.
403 
404  // Great, we can do an upper and lower bound search on our pre-search
405  // set. eg. search between 'Geoff' and 'Geofg' or 'Geoff ' and
406  // 'Geoff\33'
407 
408  var lowerBounds = prePattern.ToString();
409  int nextChar = prePattern[i - 1] + 1;
410  prePattern[i - 1] = (char)nextChar;
411  var upperBounds = prePattern.ToString();
412 
413  postPattern = pattern.Substring(i);
414 
415  var cellLower = new DataObject(colType, new SqlString(lowerBounds));
416  var cellUpper = new DataObject(colType, new SqlString(upperBounds));
417 
418  // Select rows between these two points.
419 
420  searchCase = table.SelectRowsBetween(column, cellLower, cellUpper);
421  }
422 
423  // ---------- Post search ----------
424 
425  int preIndex = i;
426 
427  // Now eliminate from our 'search_case' any cells that don't match our
428  // search pattern.
429  // Note that by this point 'post_pattern' will start with a wild card.
430  // This follows the specification for the 'PatternMatch' method.
431  // EFFICIENCY: This is a brute force iterative search. Perhaps there is
432  // a faster way of handling this?
433 
434  var iList = new BlockIndex<int>(searchCase);
435  var enumerator = iList.GetEnumerator(0, iList.Count - 1);
436 
437  while (enumerator.MoveNext()) {
438  // Get the expression (the contents of the cell at the given column, row)
439 
440  bool patternMatches = false;
441  var cell = table.GetValue(enumerator.Current, column);
442  // Null values doesn't match with anything
443  if (!cell.IsNull) {
444  string expression = cell.AsVarChar().Value.ToString();
445  // We must remove the head of the string, which has already been
446  // found from the pre-search section.
447  expression = expression.Substring(preIndex);
448  patternMatches = PatternSearch.PatternMatch(postPattern, expression, escapeChar);
449  }
450  if (!patternMatches) {
451  // If pattern does not match then remove this row from the search.
452  enumerator.Remove();
453  }
454  }
455 
456  return iList.ToList();
457  }
static DataObject String(string s)
Definition: DataObject.cs:592
SqlExpressionType
All the possible type of SqlExpression supported
static bool PatternMatch(string pattern, string expression, char escapeChar)
This is the pattern match recurrsive method.
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
static bool IsWildCard(char ch)
Returns true if the given character is a wild card (unknown).
static IEnumerable< int > SelectRows(this ITable table, IVariableResolver resolver, IRequest context, SqlBinaryExpression expression)
This is a static class that performs the operations to do a pattern search on a given column of a tab...
Deveel.Data.Sql.Objects.SqlString SqlString
Definition: DataObject.cs:27
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelecRowsLess ( this ITable  table,
int  columnOffset,
DataObject  value 
)
inlinestatic

Definition at line 215 of file TableQueryExtensions.cs.

215  {
216  return table.GetIndex(columnOffset).SelectLess(value);
217  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelecRowsLess ( this ITable  table,
int  columnOffset,
ISqlObject  value 
)
inlinestatic

Definition at line 219 of file TableQueryExtensions.cs.

219  {
220  return table.SelecRowsLess(columnOffset, table.MakeObject(columnOffset, value));
221  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Select ( this ITable  table,
IRequest  context,
SqlExpression  expression 
)
inlinestatic

Definition at line 476 of file TableQueryExtensions.cs.

476  {
477  if (expression is SqlBinaryExpression) {
478  var binary = (SqlBinaryExpression)expression;
479 
480  // Perform the pattern search expression on the table.
481  // Split the expression,
482  var leftRef = binary.Left.AsReferenceName();
483  if (leftRef != null)
484  // LHS is a simple variable so do a simple select
485  return table.SimpleSelect(context, leftRef, binary.ExpressionType, binary.Right);
486  }
487 
488  // LHS must be a constant so we can just evaluate the expression
489  // and see if we get true, false, null, etc.
490  var v = expression.EvaluateToConstant(context, null);
491 
492  // If it evaluates to NULL or FALSE then return an empty set
493  if (v.IsNull || v == false)
494  return table.EmptySelect();
495 
496  return table;
497  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.SelectAll ( this ITable  table,
int  columnOffset 
)
inlinestatic

Definition at line 472 of file TableQueryExtensions.cs.

472  {
473  return table.AsVirtual(() => table.SelectAllRows(columnOffset));
474  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectAllRows ( this ITable  table,
int  columnOffset 
)
inlinestatic

Definition at line 231 of file TableQueryExtensions.cs.

231  {
232  return table.GetIndex(columnOffset).SelectAll();
233  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectAllRows ( this ITable  table)
inlinestatic

Definition at line 235 of file TableQueryExtensions.cs.

235  {
236  return table.Select(x => x.RowId.RowNumber);
237  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.SelectAnyAllNonCorrelated ( this ITable  table,
ObjectName[]  leftColumns,
SqlExpressionType  op,
ITable  rightTable 
)
inlinestatic

Definition at line 752 of file TableQueryExtensions.cs.

752  {
753  if (rightTable.TableInfo.ColumnCount != leftColumns.Length) {
754  throw new ArgumentException(String.Format("The right table has {0} columns that is different from the specified column names ({1})",
755  rightTable.TableInfo.ColumnCount, leftColumns.Length));
756  }
757 
758  // Handle trivial case of no entries to select from
759  if (table.RowCount == 0)
760  return table;
761 
762  // Resolve the vars in the left table and check the references are
763  // compatible.
764  var sz = leftColumns.Length;
765  var leftColMap = new int[sz];
766  var rightColMap = new int[sz];
767  for (int i = 0; i < sz; ++i) {
768  leftColMap[i] = table.FindColumn(leftColumns[i]);
769  rightColMap[i] = i;
770 
771  if (leftColMap[i] == -1)
772  throw new Exception("Invalid reference: " + leftColumns[i]);
773 
774  var leftType = table.TableInfo[leftColMap[i]].ColumnType;
775  var rightType = rightTable.TableInfo[i].ColumnType;
776  if (!leftType.IsComparable(rightType)) {
777  throw new ArgumentException(String.Format("The type of the sub-query expression {0}({1}) " +
778  "is not compatible with the sub-query type {2}.",
779  leftColumns[i], leftType, rightType));
780  }
781  }
782 
783  IEnumerable<int> rows;
784 
785  if (!op.IsSubQuery())
786  throw new ArgumentException(String.Format("The operator {0} is not a sub-query form.", op));
787 
788  if (op.IsAll()) {
789  // ----- ALL operation -----
790  // We work out as follows:
791  // For >, >= type ALL we find the highest value in 'table' and
792  // select from 'source' all the rows that are >, >= than the
793  // highest value.
794  // For <, <= type ALL we find the lowest value in 'table' and
795  // select from 'source' all the rows that are <, <= than the
796  // lowest value.
797  // For = type ALL we see if 'table' contains a single value. If it
798  // does we select all from 'source' that equals the value, otherwise an
799  // empty table.
800  // For <> type ALL we use the 'not in' algorithm.
801 
802  if (op == SqlExpressionType.AllGreaterThan ||
803  op == SqlExpressionType.AllGreaterOrEqualThan) {
804  // Select the last from the set (the highest value),
805  var highestCells = rightTable.GetLastValues(rightColMap);
806  // Select from the source table all rows that are > or >= to the
807  // highest cell,
808  rows = table.SelectRows(leftColMap, op, highestCells);
809  } else if (op == SqlExpressionType.AllSmallerThan ||
810  op == SqlExpressionType.AllSmallerOrEqualThan) {
811  // Select the first from the set (the lowest value),
812  var lowestCells = rightTable.GetFirstValues(rightColMap);
813  // Select from the source table all rows that are < or <= to the
814  // lowest cell,
815  rows = table.SelectRows(leftColMap, op, lowestCells);
816  } else if (op == SqlExpressionType.AllEqual) {
817  // Select the single value from the set (if there is one).
818  var singleCell = rightTable.GetSingleValues(rightColMap);
819  if (singleCell != null) {
820  // Select all from source_table all values that = this cell
821  rows = table.SelectRows(leftColMap, op, singleCell);
822  } else {
823  // No single value so return empty set (no value in LHS will equal
824  // a value in RHS).
825  return table.EmptySelect();
826  }
827  } else if (op == SqlExpressionType.AllNotEqual) {
828  // Equiv. to NOT IN
829  rows = table.SelectRowsNotIn(rightTable, leftColMap, rightColMap);
830  } else {
831  throw new ArgumentException(String.Format("Operator of type {0} is not valid in ALL functions.", op.SubQueryPlainType()));
832  }
833  } else {
834  // ----- ANY operation -----
835  // We work out as follows:
836  // For >, >= type ANY we find the lowest value in 'table' and
837  // select from 'source' all the rows that are >, >= than the
838  // lowest value.
839  // For <, <= type ANY we find the highest value in 'table' and
840  // select from 'source' all the rows that are <, <= than the
841  // highest value.
842  // For = type ANY we use same method from INHelper.
843  // For <> type ANY we iterate through 'source' only including those
844  // rows that a <> query on 'table' returns size() != 0.
845 
846  if (op == SqlExpressionType.AnyGreaterThan ||
847  op == SqlExpressionType.AnyGreaterOrEqualThan) {
848  // Select the first from the set (the lowest value),
849  var lowestCells = rightTable.GetFirstValues(rightColMap);
850  // Select from the source table all rows that are > or >= to the
851  // lowest cell,
852  rows = table.SelectRows(leftColMap, op, lowestCells);
853  } else if (op == SqlExpressionType.AnySmallerThan ||
854  op == SqlExpressionType.AnySmallerOrEqualThan) {
855  // Select the last from the set (the highest value),
856  var highestCells = rightTable.GetLastValues(rightColMap);
857  // Select from the source table all rows that are < or <= to the
858  // highest cell,
859  rows = table.SelectRows(leftColMap, op, highestCells);
860  } else if (op == SqlExpressionType.AnyEqual) {
861  // Equiv. to IN
862  rows = table.SelectRowsIn(rightTable, leftColMap, rightColMap);
863  } else if (op == SqlExpressionType.AnyNotEqual) {
864  // Select the value that is the same of the entire column
865  var cells = rightTable.GetSingleValues(rightColMap);
866  if (cells != null) {
867  // All values from 'source_table' that are <> than the given cell.
868  rows = table.SelectRows(leftColMap, op, cells);
869  } else {
870  // No, this means there are different values in the given set so the
871  // query evaluates to the entire table.
872  return table;
873  }
874  } else {
875  throw new ArgumentException(String.Format("Operator of type {0} is not valid in ANY functions.", op.SubQueryPlainType()));
876  }
877  }
878 
879  return new VirtualTable(table, rows.ToArray());
880  }
A long string in the system.
SqlExpressionType
All the possible type of SqlExpression supported
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.SelectEqual ( this ITable  table,
int  columnIndex,
DataObject  value 
)
inlinestatic

Definition at line 463 of file TableQueryExtensions.cs.

463  {
464  return table.AsVirtual(() => table.SelectRowsEqual(columnIndex, value));
465  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.SelectEqual ( this ITable  table,
string  columnName,
DataObject  value 
)
inlinestatic

Definition at line 468 of file TableQueryExtensions.cs.

468  {
469  return table.AsVirtual(() => table.SelectRowsEqual(columnName, value));
470  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectFirst ( this ITable  table,
int  columnOffset 
)
inlinestatic

Definition at line 243 of file TableQueryExtensions.cs.

243  {
244  return table.GetIndex(columnOffset).SelectFirst();
245  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectFromPattern ( this ITable  table,
int  column,
SqlExpressionType  op,
DataObject  ob 
)
inlinestatic

Definition at line 620 of file TableQueryExtensions.cs.

620  {
621  if (ob.IsNull)
622  return new List<int>();
623 
624  if (op == SqlExpressionType.NotLike) {
625  // How this works:
626  // Find the set or rows that are like the pattern.
627  // Find the complete set of rows in the column.
628  // Sort the 'like' rows
629  // For each row that is in the original set and not in the like set,
630  // add to the result list.
631  // Result is the set of not like rows ordered by the column.
632 
633  var likeSet = (List<int>)table.Search(column, ob.ToString());
634  // Don't include NULL values
635  var nullCell = DataObject.Null(ob.Type);
636  IList<int> originalSet = table.SelectRows(column, SqlExpressionType.IsNot, nullCell).ToList();
637  int listSize = System.Math.Max(4, (originalSet.Count - likeSet.Count) + 4);
638  List<int> resultSet = new List<int>(listSize);
639  likeSet.Sort();
640  int size = originalSet.Count;
641  for (int i = 0; i < size; ++i) {
642  int val = originalSet[i];
643  // If val not in like set, add to result
644  if (likeSet.BinarySearch(val) == 0) {
645  resultSet.Add(val);
646  }
647  }
648  return resultSet;
649  }
650 
651  // if (op.is("like")) {
652  return table.Search(column, ob.ToString());
653  }
bool IsNull
Gets a value that indicates if this object is materialized as null.
Definition: DataObject.cs:91
SqlType Type
Gets the SqlType that defines the object properties
Definition: DataObject.cs:78
static DataObject Null(SqlType type)
Definition: DataObject.cs:630
SqlExpressionType
All the possible type of SqlExpression supported
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectLast ( this ITable  table,
int  columnOffset 
)
inlinestatic

Definition at line 239 of file TableQueryExtensions.cs.

239  {
240  return table.GetIndex(columnOffset).SelectLast();
241  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectNotEqual ( this ITable  table,
int  columnOffset,
DataObject  value 
)
inlinestatic

Definition at line 174 of file TableQueryExtensions.cs.

174  {
175  return table.GetIndex(columnOffset).SelectNotEqual(value);
176  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectNotEqual ( this ITable  table,
int  columnOffset,
ISqlObject  value 
)
inlinestatic

Definition at line 178 of file TableQueryExtensions.cs.

178  {
179  return table.SelectNotEqual(columnOffset, table.MakeObject(columnOffset, value));
180  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRange ( this ITable  thisTable,
ObjectName  columnName,
IndexRange[]  ranges 
)
inlinestatic

Definition at line 705 of file TableQueryExtensions.cs.

705  {
706  // If this table is empty then there is no range to select so
707  // trivially return this object.
708  if (thisTable.RowCount == 0)
709  return thisTable;
710 
711  // Are we selecting a black or null range?
712  if (ranges == null || ranges.Length == 0)
713  // Yes, so return an empty table
714  return thisTable.EmptySelect();
715 
716  // Are we selecting the entire range?
717  if (ranges.Length == 1 &&
718  ranges[0].Equals(IndexRange.FullRange))
719  // Yes, so return this table.
720  return thisTable;
721 
722  // Must be a non-trivial range selection.
723 
724  // Find the column index of the column selected
725  int column = thisTable.IndexOfColumn(columnName);
726 
727  if (column == -1) {
728  throw new Exception(
729  "Unable to find the column given to select the range of: " +
730  columnName.Name);
731  }
732 
733  // Select the range
734  var rows = thisTable.SelectRowsRange(column, ranges);
735 
736  // Make a new table with the range selected
737  var result = new VirtualTable(thisTable, rows.ToArray());
738 
739  // We know the new set is ordered by the column.
740  result.SortColumn = column;
741 
742  return result;
743  }
Describes the range of values to select from an index.
Definition: IndexRange.cs:38
static readonly IndexRange FullRange
The entire range of values in an index (including NULL)
Definition: IndexRange.cs:74
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRows ( this ITable  table,
IVariableResolver  resolver,
IRequest  context,
SqlBinaryExpression  expression 
)
inlinestatic

Definition at line 247 of file TableQueryExtensions.cs.

250  {
251 
252  var objRef = expression.Left as SqlReferenceExpression;
253  if (objRef == null)
254  throw new NotSupportedException();
255 
256  var columnName = objRef.ReferenceName;
257 
258  var column = table.FindColumn(columnName);
259  if (column < 0)
260  throw new InvalidOperationException();
261 
262  var reduced = expression.Right.Evaluate(context, resolver);
263  if (reduced.ExpressionType != SqlExpressionType.Constant)
264  throw new InvalidOperationException();
265 
266  var value = ((SqlConstantExpression) reduced).Value;
267  var binOperator = expression.ExpressionType;
268 
269  return table.SelectRows(column, binOperator, value);
270  }
An expression that references an object within a context.
SqlExpressionType
All the possible type of SqlExpression supported
virtual SqlExpression Evaluate(EvaluateContext context)
When overridden by a derived class, this method evaluates the expression within the provided context...
An expression that holds a constant value.
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRows ( this ITable  table,
int[]  columnOffsets,
SqlExpressionType  op,
DataObject[]  values 
)
inlinestatic

Definition at line 272 of file TableQueryExtensions.cs.

273  {
274  if (columnOffsets.Length > 1)
275  throw new NotSupportedException("Multi-column selects not supported yet.");
276 
277  return SelectRows(table, columnOffsets[0], op, values[0]);
278  }
static IEnumerable< int > SelectRows(this ITable table, IVariableResolver resolver, IRequest context, SqlBinaryExpression expression)
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRows ( this ITable  table,
int  column,
SqlExpressionType  op,
DataObject  value 
)
inlinestatic

Definition at line 292 of file TableQueryExtensions.cs.

292  {
293  // If the cell is of an incompatible type, return no results,
294  var colType = table.TableInfo[column].ColumnType;
295  if (!value.Type.IsComparable(colType)) {
296  // Types not comparable, so return 0
297  return new List<int>(0);
298  }
299 
300  // Get the selectable scheme for this column
301  var index = table.GetIndex(column);
302 
303  // If the operator is a standard operator, use the interned SelectableScheme
304  // methods.
305  if (op == SqlExpressionType.Equal)
306  return index.SelectEqual(value);
307  if (op == SqlExpressionType.NotEqual)
308  return index.SelectNotEqual(value);
309  if (op == SqlExpressionType.GreaterThan)
310  return index.SelectGreater(value);
311  if (op == SqlExpressionType.SmallerThan)
312  return index.SelectLess(value);
313  if (op == SqlExpressionType.GreaterOrEqualThan)
314  return index.SelectGreaterOrEqual(value);
315  if (op == SqlExpressionType.SmallerOrEqualThan)
316  return index.SelectLessOrEqual(value);
317 
318  // If it's not a standard operator (such as IS, NOT IS, etc) we generate the
319  // range set especially.
320  var rangeSet = new IndexRangeSet();
321  rangeSet = rangeSet.Intersect(op, value);
322  return index.SelectRange(rangeSet.ToArray());
323  }
SqlType Type
Gets the SqlType that defines the object properties
Definition: DataObject.cs:78
virtual bool IsComparable(SqlType type)
Verifies if a given SqlType is comparable to this data-type.
Definition: SqlType.cs:137
SqlExpressionType
All the possible type of SqlExpression supported
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsBetween ( this ITable  table,
int  column,
DataObject  minCell,
DataObject  maxCell 
)
inlinestatic

Definition at line 280 of file TableQueryExtensions.cs.

280  {
281  // Check all the tables are comparable
282  var colType = table.TableInfo[column].ColumnType;
283  if (!minCell.Type.IsComparable(colType) ||
284  !maxCell.Type.IsComparable(colType)) {
285  // Types not comparable, so return 0
286  return new List<int>(0);
287  }
288 
289  return table.GetIndex(column).SelectBetween(minCell, maxCell);
290  }
SqlType Type
Gets the SqlType that defines the object properties
Definition: DataObject.cs:78
virtual bool IsComparable(SqlType type)
Verifies if a given SqlType is comparable to this data-type.
Definition: SqlType.cs:137
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsEqual ( this ITable  table,
int  columnIndex,
DataObject  value 
)
inlinestatic

Definition at line 166 of file TableQueryExtensions.cs.

166  {
167  return table.GetIndex(columnIndex).SelectEqual(value);
168  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsEqual ( this ITable  table,
string  columnName,
DataObject  value 
)
inlinestatic

Definition at line 170 of file TableQueryExtensions.cs.

170  {
171  return table.SelectRowsEqual(table.IndexOfColumn(columnName), value);
172  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsEqual ( this ITable  table,
int  columnIndex1,
DataObject  value1,
int  columnIndex2,
DataObject  value2 
)
inlinestatic

Definition at line 182 of file TableQueryExtensions.cs.

182  {
183  var result = new List<int>();
184 
185  var index1 = table.GetIndex(columnIndex1).SelectEqual(value1);
186  foreach (var rowIndex in index1) {
187  var tableValue = table.GetValue(rowIndex, columnIndex2);
188  if (tableValue.IsEqualTo(value2))
189  result.Add(rowIndex);
190  }
191 
192  return result;
193  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsGreater ( this ITable  table,
int  columnOffset,
DataObject  value 
)
inlinestatic

Definition at line 199 of file TableQueryExtensions.cs.

199  {
200  return table.GetIndex(columnOffset).SelectGreater(value);
201  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsGreater ( this ITable  table,
int  columnOffset,
ISqlObject  value 
)
inlinestatic

Definition at line 203 of file TableQueryExtensions.cs.

203  {
204  return table.SelectRowsGreater(columnOffset, table.MakeObject(columnOffset, value));
205  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsGreaterOrEqual ( this ITable  table,
int  columnOffset,
DataObject  value 
)
inlinestatic

Definition at line 207 of file TableQueryExtensions.cs.

207  {
208  return table.GetIndex(columnOffset).SelectGreaterOrEqual(value);
209  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsGreaterOrEqual ( this ITable  table,
int  columnOffset,
ISqlObject  value 
)
inlinestatic

Definition at line 211 of file TableQueryExtensions.cs.

211  {
212  return table.SelectRowsGreaterOrEqual(columnOffset, table.MakeObject(columnOffset, value));
213  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsIn ( this ITable  table,
ITable  other,
int  column1,
int  column2 
)
inlinestatic

This implements the in command.

Parameters
table
other
column1
column2
Returns
Returns the rows selected from table1 .

Definition at line 921 of file TableQueryExtensions.cs.

921  {
922  // First pick the the smallest and largest table. We only want to iterate
923  // through the smallest table.
924  // NOTE: This optimisation can't be performed for the 'not_in' command.
925 
926  ITable smallTable;
927  ITable largeTable;
928  int smallColumn;
929  int largeColumn;
930 
931  if (table.RowCount < other.RowCount) {
932  smallTable = table;
933  largeTable = other;
934 
935  smallColumn = column1;
936  largeColumn = column2;
937 
938  } else {
939  smallTable = other;
940  largeTable = table;
941 
942  smallColumn = column2;
943  largeColumn = column1;
944  }
945 
946  // Iterate through the small table's column. If we can find identical
947  // cells in the large table's column, then we should include the row in our
948  // final result.
949 
950  var resultRows = new BlockIndex<int>();
951  var op = SqlExpressionType.Equal;
952 
953  foreach (var row in smallTable) {
954  var cell = row.GetValue(smallColumn);
955 
956  var selectedSet = largeTable.SelectRows(largeColumn, op, cell).ToList();
957 
958  // We've found cells that are IN both columns,
959 
960  if (selectedSet.Count > 0) {
961  // If the large table is what our result table will be based on, append
962  // the rows selected to our result set. Otherwise add the index of
963  // our small table. This only works because we are performing an
964  // EQUALS operation.
965 
966  if (largeTable == table) {
967  // Only allow unique rows into the table set.
968  int sz = selectedSet.Count;
969  bool rs = true;
970  for (int i = 0; rs && i < sz; ++i) {
971  rs = resultRows.UniqueInsertSort(selectedSet[i]);
972  }
973  } else {
974  // Don't bother adding in sorted order because it's not important.
975  resultRows.Add(row.RowId.RowNumber);
976  }
977  }
978  }
979 
980  return resultRows.ToList();
981  }
SqlExpressionType
All the possible type of SqlExpression supported
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsIn ( this ITable  table,
ITable  other,
int[]  t1Cols,
int[]  t2Cols 
)
inlinestatic

A multi-column version of IN.

Parameters
table
other
t1Cols
t2Cols
Returns

Definition at line 991 of file TableQueryExtensions.cs.

991  {
992  if (t1Cols.Length > 1)
993  throw new NotSupportedException("Multi-column 'in' not supported yet.");
994 
995  return table.SelectRowsIn(other, t1Cols[0], t2Cols[0]);
996  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsLessOrEqual ( this ITable  table,
int  columnOffset,
DataObject  value 
)
inlinestatic

Definition at line 223 of file TableQueryExtensions.cs.

223  {
224  return table.GetIndex(columnOffset).SelectLessOrEqual(value);
225  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsLessOrEqual ( this ITable  table,
int  columnOffset,
ISqlObject  value 
)
inlinestatic

Definition at line 227 of file TableQueryExtensions.cs.

227  {
228  return table.SelectRowsLessOrEqual(columnOffset, table.MakeObject(columnOffset, value));
229  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsNotIn ( this ITable  table,
ITable  other,
int  col1,
int  col2 
)
inlinestatic

This implements the not in command.

Parameters
table
other
col1
col2

Issue: This will be less efficient than in if table has many rows and other has few rows.

Returns

Definition at line 1010 of file TableQueryExtensions.cs.

1010  {
1011  // Handle trivial cases
1012  int t2RowCount = other.RowCount;
1013  if (t2RowCount == 0)
1014  // No rows so include all rows.
1015  return table.SelectAllRows(col1);
1016 
1017  if (t2RowCount == 1) {
1018  // 1 row so select all from table1 that doesn't equal the value.
1019  var en = other.GetEnumerator();
1020  if (!en.MoveNext())
1021  throw new InvalidOperationException("Cannot iterate through table rows.");
1022 
1023  var cell = other.GetValue(en.Current.RowId.RowNumber, col2);
1024  return table.SelectRows(col1, SqlExpressionType.NotEqual, cell);
1025  }
1026 
1027  // Iterate through table1's column. If we can find identical cell in the
1028  // tables's column, then we should not include the row in our final
1029  // result.
1030  List<int> resultRows = new List<int>();
1031 
1032  foreach (var row in table) {
1033  int rowIndex = row.RowId.RowNumber;
1034  var cell = row.GetValue(col1);
1035 
1036  var selectedSet = other.SelectRows(col2, SqlExpressionType.Equal, cell);
1037 
1038  // We've found a row in table1 that doesn't have an identical cell in
1039  // other, so we should include it in the result.
1040 
1041  if (!selectedSet.Any())
1042  resultRows.Add(rowIndex);
1043  }
1044 
1045  return resultRows;
1046  }
SqlExpressionType
All the possible type of SqlExpression supported
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsNotIn ( this ITable  table,
ITable  other,
int[]  t1Cols,
int[]  t2Cols 
)
inlinestatic

A multi-column version of NOT IN.

Parameters
table1
other
t1Cols
t2Cols
Returns

Definition at line 1056 of file TableQueryExtensions.cs.

1056  {
1057  if (t1Cols.Length > 1)
1058  throw new NotSupportedException("Multi-column 'not in' not supported yet.");
1059 
1060  return table.SelectRowsNotIn(other, t1Cols[0], t2Cols[0]);
1061  }
static IEnumerable<int> Deveel.Data.Sql.Tables.TableQueryExtensions.SelectRowsRange ( this ITable  table,
int  column,
IndexRange[]  ranges 
)
inlinestatic

Definition at line 195 of file TableQueryExtensions.cs.

195  {
196  return table.GetIndex(column).SelectRange(ranges);
197  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.SimpleJoin ( this ITable  thisTable,
IRequest  context,
ITable  other,
SqlBinaryExpression  binary 
)
inlinestatic

Definition at line 1168 of file TableQueryExtensions.cs.

1168  {
1169  var objRef = binary.Left as SqlReferenceExpression;
1170  if (objRef == null)
1171  throw new ArgumentException();
1172 
1173  // Find the row with the name given in the condition.
1174  int lhsColumn = thisTable.FindColumn(objRef.ReferenceName);
1175 
1176  if (lhsColumn == -1)
1177  throw new Exception("Unable to find the LHS column specified in the condition: " + objRef.ReferenceName);
1178 
1179  // Create a variable resolver that can resolve columns in the destination
1180  // table.
1181  var resolver = other.GetVariableResolver();
1182 
1183  // The join algorithm. It steps through the RHS expression, selecting the
1184  // cells that match the relation from the LHS table (this table).
1185 
1186  var thisRowSet = new List<int>();
1187  var tableRowSet = new List<int>();
1188 
1189  var e = other.GetEnumerator();
1190 
1191  while (e.MoveNext()) {
1192  int rowIndex = e.Current.RowId.RowNumber;
1193 
1194  var rowResolver = resolver.ForRow(rowIndex);
1195 
1196  // Select all the rows in this table that match the joining condition.
1197  var selectedSet = thisTable.SelectRows(rowResolver, context, binary);
1198 
1199  var selectList = selectedSet.ToList();
1200 
1201  var size = selectList.Count;
1202  // Include in the set.
1203  for (int i = 0; i < size; i++) {
1204  tableRowSet.Add(rowIndex);
1205  }
1206 
1207  thisRowSet.AddRange(selectList);
1208  }
1209 
1210  // Create the new VirtualTable with the joined tables.
1211 
1212  var tabs = new[] {thisTable, other};
1213  var rowSets = new IList<int>[] {thisRowSet, tableRowSet};
1214 
1215  return new VirtualTable(tabs, rowSets);
1216  }
An expression that references an object within a context.
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.SimpleSelect ( this ITable  table,
IRequest  context,
ObjectName  columnName,
SqlExpressionType  op,
SqlExpression  exp 
)
inlinestatic

Definition at line 499 of file TableQueryExtensions.cs.

499  {
500  // Find the row with the name given in the condition.
501  int column = table.FindColumn(columnName);
502 
503  if (column == -1)
504  throw new ArgumentException(String.Format("Unable to find the column {0} in the condition.", columnName.Name));
505 
506  // If we are doing a sub-query search
507  if (op.IsSubQuery()) {
508  // We can only handle constant expressions in the RHS expression, and
509  // we must assume that the RHS is a Expression[] array.
510  if (exp.ExpressionType != SqlExpressionType.Constant &&
511  exp.ExpressionType != SqlExpressionType.Tuple)
512  throw new ArgumentException();
513 
514  IEnumerable<SqlExpression> list;
515 
516  if (exp.ExpressionType == SqlExpressionType.Constant) {
517  var tob = ((SqlConstantExpression) exp).Value;
518  if (tob.Type is ArrayType) {
519  var array = (SqlArray) tob.Value;
520  list = array;
521  } else {
522  throw new Exception("Error with format or RHS expression.");
523  }
524  } else {
525  list = ((SqlTupleExpression) exp).Expressions;
526  }
527 
528  // Construct a temporary table with a single column that we are
529  // comparing to.
530  var col = table.TableInfo[column];
531  var ttable = TemporaryTable.SingleColumnTable(table.Context, col.ColumnName, col.ColumnType);
532 
533  foreach (var expression in list) {
534  var rowNum = ttable.NewRow();
535 
536  var evalExp = (SqlConstantExpression)expression.Evaluate(context, null, null);
537  ttable.SetValue(rowNum, 0, evalExp.Value);
538  }
539 
540  ttable.BuildIndexes();
541 
542  // Perform the any/all sub-query on the constant table.
543 
544  return table.SelectAnyAllNonCorrelated(new[] { columnName }, op, ttable);
545  }
546 
547  {
548  if (!exp.IsConstant())
549  throw new ArgumentException("The search expression is not constant.");
550 
551  var evalExp = exp.Evaluate(context, null);
552  if (evalExp.ExpressionType != SqlExpressionType.Constant)
553  throw new InvalidOperationException();
554 
555  var value = ((SqlConstantExpression) evalExp).Value;
556 
557  IEnumerable<int> rows;
558 
559  if (op == SqlExpressionType.Like ||
560  op == SqlExpressionType.NotLike
561  /* TODO: ||
562  op.IsOfType(BinaryOperatorType.Regex)*/) {
563 
564  /*
565  TODO:
566  if (op.IsOfType(BinaryOperatorType.Regex)) {
567  rows = SelectFromRegex(column, op, value);
568  } else {
569  */
570  rows = table.SelectFromPattern(column, op, value);
571  } else {
572 
573  // Is the column we are searching on indexable?
574  var colInfo = table.TableInfo[column];
575  if (!colInfo.IsIndexable)
576  throw new InvalidOperationException(String.Format("Column {0} os type {1} cannot be searched.", colInfo.ColumnName,
577  colInfo.ColumnType));
578 
579  rows = table.SelectRows(column, op, value);
580  }
581 
582  return new VirtualTable(table, rows.ToArray()) {SortColumn = column};
583  }
584  }
A long string in the system.
SqlExpressionType
All the possible type of SqlExpression supported
virtual SqlExpression Evaluate(EvaluateContext context)
When overridden by a derived class, this method evaluates the expression within the provided context...
An expression that holds a constant value.
An object that provides methods for accessing a finite collection of SQL expressions.
Definition: SqlArray.cs:28
abstract SqlExpressionType ExpressionType
Gets the type code of this SQL expression.
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Subset ( this ITable  table,
ObjectName[]  columnNames,
ObjectName[]  aliases 
)
inlinestatic

Definition at line 1360 of file TableQueryExtensions.cs.

1360  {
1361  var columnMap = new int[columnNames.Length];
1362 
1363  for (int i = 0; i < columnMap.Length; i++) {
1364  columnMap[i] = table.IndexOfColumn(columnNames[i]);
1365  }
1366 
1367  return new SubsetColumnTable(table, columnMap, aliases);
1368  }
static Dictionary<string, ISqlObject> Deveel.Data.Sql.Tables.TableQueryExtensions.ToDictionary ( this ITable  table)
inlinestatic

Definition at line 1402 of file TableQueryExtensions.cs.

1402  {
1403  if (table.TableInfo.ColumnCount != 2)
1404  throw new NotSupportedException("Table must have two columns.");
1405 
1406  var map = new Dictionary<string, ISqlObject>();
1407  foreach (var row in table) {
1408  var key = row.GetValue(0);
1409  var value = row.GetValue(1);
1410  map[key.AsVarChar().Value.ToString()] = value.Value;
1411  }
1412 
1413  return map;
1414  }
static ITable Deveel.Data.Sql.Tables.TableQueryExtensions.Union ( this ITable  thisTable,
ITable  otherTable 
)
inlinestatic

Definition at line 882 of file TableQueryExtensions.cs.

882  {
883  // Optimizations - handle trivial case of row count in one of the tables
884  // being 0.
885  // NOTE: This optimization assumes this table and the unioned table are
886  // of the same type.
887  if ((thisTable.RowCount == 0 && otherTable.RowCount == 0) ||
888  otherTable.RowCount == 0) {
889  return thisTable;
890  }
891 
892  if (thisTable.RowCount == 0)
893  return otherTable;
894 
895  // First we merge this table with the input table.
896 
897  var raw1 = thisTable.GetRawTableInfo();
898  var raw2 = otherTable.GetRawTableInfo();
899 
900  // This will throw an exception if the table types do not match up.
901 
902  var union = raw1.Union(raw2);
903 
904  // Now 'union' contains a list of uniquely merged rows (ie. the union).
905  // Now make it into a new table and return the information.
906 
907  var tableList = union.GetTables().AsEnumerable();
908  return new VirtualTable(tableList, union.GetRows());
909  }
static ITable Union(this ITable thisTable, ITable otherTable)

The documentation for this class was generated from the following file: