public FunctionTable AsGroup() { // TODO: create a new table ... wholeTableAsGroup = true; wholeTableGroupSize = ReferenceTable.RowCount; // Set up 'whole_table_group' to the list of all rows in the reference // table. var en = ReferenceTable.GetEnumerator(); wholeTableIsSimpleEnum = en is SimpleRowEnumerator; if (!wholeTableIsSimpleEnum) { wholeTableGroup = new List <int>(ReferenceTable.RowCount); while (en.MoveNext()) { wholeTableGroup.Add(en.Current.RowId.RowNumber); } } // Set up a group resolver for this method. groupResolver = new TableGroupResolver(this); return(this); }
public override void Release() { // We unlock the reference table. // NOTE: This cause the reference table to unlock twice when we use the // 'MergeWith' method. While this isn't perfect behaviour, it // means if 'MergeWithReference' isn't used, we still maintain a safe // level of locking. ReferenceTable.Release(); }
public ITable MergeWith(ObjectName maxColumn) { var table = ReferenceTable; IList <int> rowList; if (wholeTableAsGroup) { // Whole table is group, so take top entry of table. rowList = new List <int>(1); var rowEnum = table.GetEnumerator(); if (rowEnum.MoveNext()) { rowList.Add(rowEnum.Current.RowId.RowNumber); } else { // MAJOR HACK: If the referencing table has no elements then we choose // an arbitrary index from the reference table to merge so we have // at least one element in the table. // This is to fix the 'SELECT COUNT(*) FROM empty_table' bug. rowList.Add(Int32.MaxValue - 1); } } else if (table.RowCount == 0) { rowList = new List <int>(0); } else if (groupLinks != null) { // If we are grouping, reduce down to only include one row from each // group. if (maxColumn == null) { rowList = GetTopRowsFromEachGroup(); } else { var colNum = ReferenceTable.FindColumn(maxColumn); rowList = GetMaxFromEachGroup(colNum); } } else { // OPTIMIZATION: This should be optimized. It should be fairly trivial // to generate a Table implementation that efficiently merges this // function table with the reference table. // This means there is no grouping, so merge with entire table, int rowCount = table.RowCount; rowList = new List <int>(rowCount); var en = table.GetEnumerator(); while (en.MoveNext()) { rowList.Add(en.Current.RowId.RowNumber); } } // Create a virtual table that's the new group table merged with the // functions in this... var tabs = new [] { table, this }; var rowSets = new[] { rowList, rowList }; return(new VirtualTable(tabs, rowSets)); }