///<summary> ///</summary> ///<param name="left"></param> ///<param name="right"></param> public NaturallyJoinedTable(Table left, Table right) { Init(new Table[] { left, right }); leftRowCount = left.RowCount; rightRowCount = right.RowCount; // Build lookup tables for the rows in the parent tables if necessary // (usually it's not necessary). // If the left or right tables are simple enumerations, we can optimize // our access procedure, leftIsSimpleEnum = (left.GetRowEnumerator() is SimpleRowEnumerator); rightIsSimpleEnum = (right.GetRowEnumerator() is SimpleRowEnumerator); leftSet = !leftIsSimpleEnum ? CreateLookupRowList(left) : null; rightSet = !rightIsSimpleEnum ? CreateLookupRowList(right) : null; }
public static IList <long> OrdereddRows(this ITable table, int[] columns) { Table work = (Table)table.OrderBy(columns); // 'work' is now sorted by the columns, // Get the rows in this tables domain, long rowCount = table.RowCount; List <long> rowList = new List <long>((int)rowCount); IEnumerator <long> e = work.GetRowEnumerator(); while (e.MoveNext()) { rowList.Add(e.Current); } work.SetToRowTableDomain(0, rowList, table); return(rowList); }
///<summary> ///</summary> ///<param name="left"></param> ///<param name="right"></param> public NaturallyJoinedTable(Table left, Table right) { base.Init(new Table[] { left, right }); leftRowCount = left.RowCount; rightRowCount = right.RowCount; // Build lookup tables for the rows in the parent tables if necessary // (usually it's not necessary). // If the left or right tables are simple enumerations, we can optimize // our access procedure, leftIsSimpleEnum = (left.GetRowEnumerator() is SimpleRowEnumerator); rightIsSimpleEnum = (right.GetRowEnumerator() is SimpleRowEnumerator); leftSet = !leftIsSimpleEnum?CreateLookupRowList(left) : null; rightSet = !rightIsSimpleEnum?CreateLookupRowList(right) : null; }
///<summary> /// Returns a Table that is this function table merged with the cross /// reference table. ///</summary> ///<param name="maxColumn"></param> /// <remarks> /// The result table includes only one row from each group. /// <para> /// The 'max_column' argument is optional (can be null). If it's set to a /// column in the reference table, then the row with the max value from the /// group is used as the group row. For example, 'Part.id' will return the /// row with the maximum part.id from each group. /// </para> /// </remarks> ///<returns></returns> public Table MergeWithReference(ObjectName maxColumn) { Table table = ReferenceTable; IList <long> rowList; if (wholeTableAsGroup) { // Whole table is group, so take top entry of table. rowList = new List <long>(1); IEnumerator <long> rowEnum = table.GetRowEnumerator(); if (rowEnum.MoveNext()) { rowList.Add(rowEnum.Current); } else { // MAJOR HACK: If the referencing table has no elements then we choose // an arbitary 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 <long>(0); } else if (groupLinks != null) { // If we are grouping, reduce down to only include one row from each // group. if (maxColumn == null) { rowList = GetTopFromEachGroup(); } else { int col_num = ReferenceTable.FindFieldName(maxColumn); rowList = GetMaxFromEachGroup(col_num); } } 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, long rowCount = table.RowCount; rowList = new List <long>((int)rowCount); IEnumerator <long> en = table.GetRowEnumerator(); while (en.MoveNext()) { rowList.Add(en.Current); } } // Create a virtual table that's the new group table merged with the // functions in this... Table[] tabs = new Table[] { table, this }; IList <long>[] rowSets = new IList <long>[] { rowList, rowList }; VirtualTable outTable = new VirtualTable(tabs); outTable.Set(tabs, rowSets); table = outTable; return(table); }
/// <summary> /// Constructs the result set. /// </summary> /// <param name="query"></param> /// <param name="result"></param> public QueryResult(SqlQuery query, Table result) { this.query = query; this.result = result; streamableBlobMap = new Dictionary<long, StreamableObject>(); resultRowCount = result.RowCount; // HACK: Read the contents of the first row so that we can pick up // any errors with reading, and also to fix the 'uniquekey' bug // that causes a new transaction to be started if 'uniquekey' is // a column and the value is resolved later. IRowEnumerator rowEnum = result.GetRowEnumerator(); if (rowEnum.MoveNext()) { int rowIndex = rowEnum.RowIndex; for (int c = 0; c < result.ColumnCount; ++c) { result.GetCell(c, rowIndex); } } // If simple enum, note it here resultIsSimpleEnum = (rowEnum is SimpleRowEnumerator); rowEnum = null; // Build 'row_index_map' if not a simple enum if (!resultIsSimpleEnum) { rowIndexMap = new List<int>(result.RowCount); IRowEnumerator en = result.GetRowEnumerator(); while (en.MoveNext()) { rowIndexMap.Add(en.RowIndex); } } // This is a safe operation provides we are shared. // Copy all the TableField columns from the table to our own // QueryResultColumn array, naming each column by what is returned from // the 'GetResolvedVariable' method. int colCount = result.ColumnCount; colDesc = new QueryResultColumn[colCount]; for (int i = 0; i < colCount; ++i) { VariableName v = result.GetResolvedVariable(i); string fieldName; if (v.TableName == null) { // This means the column is an alias fieldName = String.Format("@a{0}", v.Name); } else { // This means the column is an schema/table/column reference fieldName = String.Format("@f{0}", v); } colDesc[i] = new QueryResultColumn(fieldName, result.GetColumnInfo(i)); } locked = 0; }