///<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;
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        ///<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;
        }
Esempio n. 4
0
        ///<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);
        }
Esempio n. 5
0
        /// <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;
        }