private static Result RemoveSecond(Result result, Result minus) { int len = result.ColumnCount; Record n = result.Root; Record last = result.Root; bool rootr = true; // checking rootrecord Record n2 = minus.Root; int i = 0; while (n != null && n2 != null) { i = CompareRecord(n.Data, n2.Data, result, len); if (i == 0) { if (rootr) { result.SetRoot(n.Next); } else { last.Next = n.Next; } n = n.Next; } else if (i > 0) { // r > minus n2 = n2.Next; } else { // r < minus last = n; rootr = false; n = n.Next; } } return(result); }
private static Result RemoveDuplicates(Result result) { int len = result.ColumnCount; int[] order = new int[len]; int[] way = new int[len]; for (int i = 0; i < len; i++) { order[i] = i; way[i] = 1; } result = SortResult(result, order, way); Record n = result.Root; while (n != null) { Record next = n.Next; if (next == null) { break; } if (CompareRecord(n.Data, next.Data, result, len) == 0) { n.Next = next.Next; } else { n = n.Next; } } return(result); }
/// <summary> /// Sets the result root record. /// </summary> /// <param name="root"></param> internal void SetRoot( Record root ) { _root = root; }
/// <summary> /// Append a result to this results. /// </summary> /// <param name="result"></param> internal void Append(Result result) { if (_root == null) { _root = result.Root; } else { _tailRecord.Next = result.Root; } _tailRecord = result._tailRecord; _size += result._size; }
/// <summary> /// Add a row to this results. /// </summary> /// <param name="d"></param> internal void Add(object[] d) { Record r = new Record(); r.Data = d; if (_root == null) { _root = r; } else { _tailRecord.Next = r; } _tailRecord = r; _size++; }
private static Result SortResult(Result r, int[] order, int[] way) { if (r.Root == null || r.Root.Next == null) { return r; } Record source0, source1; Record[] target = new Record[2]; Record[] targetlast = new Record[2]; int dest = 0; Record n = r.Root; while (n != null) { Record next = n.Next; n.Next = target[dest]; target[dest] = n; n = next; dest ^= 1; } for (int blocksize = 1; target[1] != null; blocksize <<= 1) { source0 = target[0]; source1 = target[1]; target[0] = target[1] = targetlast[0] = targetlast[1] = null; for (dest = 0; source0 != null; dest ^= 1) { int n0 = blocksize, n1 = blocksize; while (true) { if (n0 == 0 || source0 == null) { if (n1 == 0 || source1 == null) { break; } n = source1; source1 = source1.Next; n1--; } else if (n1 == 0 || source1 == null) { n = source0; source0 = source0.Next; n0--; } else if (CompareRecord(source0.Data, source1.Data, r, order, way) > 0) { n = source1; source1 = source1.Next; n1--; } else { n = source0; source0 = source0.Next; n0--; } if (target[dest] == null) { target[dest] = n; } else { targetlast[dest].Next = n; } targetlast[dest] = n; n.Next = null; } } } r.SetRoot( target[0] ); return r; }
private static Result SortResult(Result r, int[] order, int[] way) { if (r.Root == null || r.Root.Next == null) { return(r); } Record source0, source1; Record[] target = new Record[2]; Record[] targetlast = new Record[2]; int dest = 0; Record n = r.Root; while (n != null) { Record next = n.Next; n.Next = target[dest]; target[dest] = n; n = next; dest ^= 1; } for (int blocksize = 1; target[1] != null; blocksize <<= 1) { source0 = target[0]; source1 = target[1]; target[0] = target[1] = targetlast[0] = targetlast[1] = null; for (dest = 0; source0 != null; dest ^= 1) { int n0 = blocksize, n1 = blocksize; while (true) { if (n0 == 0 || source0 == null) { if (n1 == 0 || source1 == null) { break; } n = source1; source1 = source1.Next; n1--; } else if (n1 == 0 || source1 == null) { n = source0; source0 = source0.Next; n0--; } else if (CompareRecord(source0.Data, source1.Data, r, order, way) > 0) { n = source1; source1 = source1.Next; n1--; } else { n = source0; source0 = source0.Next; n0--; } if (target[dest] == null) { target[dest] = n; } else { targetlast[dest].Next = n; } targetlast[dest] = n; n.Next = null; } } } r.SetRoot(target[0]); return(r); }
// [email protected] end changes from 1.50 // [email protected] begin changes from 1.50 public Result GetResult(int start, int cnt, Channel cChannel) { int maxrows = start + cnt; //<-new, cut definitly // [email protected] begin changes from 1.50 Resolve(); CheckResolved(); if (sUnion != null && sUnion.iResultLen != iResultLen) { throw TracingHelper.Error(TracingHelper.COLUMN_COUNT_DOES_NOT_MATCH); } int len = eColumn.Length; Result r = new Result(len); bool aggregated = false; bool grouped = false; for (int i = 0; i < len; i++) { Expression e = eColumn[i]; r.Type[i] = e.ColumnType; if (e.IsAggregate) { aggregated = true; } } object[] agg = null; if (aggregated) { agg = new object[len]; } if (iGroupLen > 0) { // has been set in Parser grouped = true; } bool simple_maxrows = false; if (maxrows != 0 && grouped == false && sUnion == null && iOrderLen == 0) { simple_maxrows = true; } int count = 0; int filter = tFilter.Length; bool[] first = new bool[filter]; int level = 0; while (level >= 0) { bool found = false; if (filter > 0) { TableFilter t = tFilter[level]; if (!first[level]) { found = t.FindFirst(); first[level] = found; } else { found = t.Next(); first[level] = found; } } if (!found) { level--; if (!OnlyVars) { continue; } } if (level < filter - 1) { level++; continue; } if (eCondition == null || eCondition.Test()) { object[] row = new object[len]; for (int i = 0; i < len; i++) { row[i] = eColumn[i].GetValue(); if (cChannel != null && eColumn[i].IsVarAssign) { cChannel.SetDeclareValue(eColumn[i].Arg.ColumnName, row[i]); } } count++; if (aggregated && !grouped) { UpdateAggregateRow(agg, row, len); } else { r.Add(row); if (simple_maxrows && count >= maxrows) { break; } } } } if (aggregated && !grouped) { AddAggregateRow(r, agg, len, count); } else if (grouped) { int[] order = new int[iGroupLen]; int[] way = new int[iGroupLen]; for (int i = iResultLen, j = 0; j < iGroupLen; i++, j++) { order[j] = i; way[j] = 1; } r = SortResult(r, order, way); Record n = r.Root; Result x = new Result(len); for (int i = 0; i < len; i++) { x.Type[i] = r.Type[i]; } do { object[] row = new object[len]; count = 0; bool newgroup = false; while (n != null && newgroup == false) { count++; for (int i = 0; i < iGroupLen; i++) { if (n.Next == null) { newgroup = true; } else if (Column.Compare(n.Data[i], n.Next.Data[i], r.Type[i]) != 0) { // can't use .Equals because 'null' is also one group newgroup = true; } } UpdateAggregateRow(row, n.Data, len); n = n.Next; } AddAggregateRow(x, row, len, count); } while (n != null); r = x; } if (iOrderLen != 0) { int[] order = new int[iOrderLen]; int[] way = new int[iOrderLen]; for (int i = iResultLen, j = 0; j < iOrderLen; i++, j++) { order[j] = i; way[j] = eColumn[i].IsDescending ? -1 : 1; } r = SortResult(r, order, way); } // the result maybe is bigger (due to group and order by) // but don't tell this anybody else r.SetColumnCount(iResultLen); if (bDistinct) { r = RemoveDuplicates(r); } for (int i = 0; i < iResultLen; i++) { Expression e = eColumn[i]; r.Label[i] = e.Alias; r.Table[i] = e.TableName; r.Name[i] = e.ColumnName; } if (sUnion != null) { Result x = sUnion.GetResult(0, cChannel); if (UnionType == SelectType.Union) { r.Append(x); r = RemoveDuplicates(r); } else if (UnionType == SelectType.UnionAll) { r.Append(x); } else if (UnionType == SelectType.Intersect) { r = RemoveDuplicates(r); x = RemoveDuplicates(x); r = RemoveDifferent(r, x); } else if (UnionType == SelectType.Except) { r = RemoveDuplicates(r); x = RemoveDuplicates(x); r = RemoveSecond(r, x); } } if (maxrows > 0 && !simple_maxrows) { TrimResult(r, maxrows); } // [email protected] begin changes from 1.50 if (start > 0) { //then cut the first 'start' elements TrimResultFront(r, start); } // [email protected] end changes from 1.50 return(r); }