Пример #1
0
// Do implements plan.Plan Do interface, all records are added into an
// in-memory array, and sorted in ASC/DESC order.
func (r *OrderByDefaultPlan) Do(ctx context.Context, f plan.RowIterFunc) error {
	t := &orderByTable{Ascs: r.Ascs}

	m := map[interface{}]interface{}{}
	err := r.Src.Do(ctx, func(rid interface{}, in []interface{}) (bool, error) {
		m[expressions.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
			return getIdentValue(name, r.ResultFields, in, field.CheckFieldFlag)
		}

		m[expressions.ExprEvalPositionFunc] = func(position int) (interface{}, error) {
			// position is in [1, len(fields)], so we must decrease 1 to get correct index
			// TODO: check position invalidation
			return in[position-1], nil
		}

		row := &orderByRow{
			Row: in,
			Key: make([]interface{}, 0, len(r.By)),
		}

		for _, by := range r.By {
			// err1 is used for passing `go tool vet --shadow` check.
			val, err1 := by.Eval(ctx, m)
			if err1 != nil {
				return false, err1
			}

			if val != nil {
				var ordered bool
				val, ordered, err1 = types.IsOrderedType(val)
				if err1 != nil {
					return false, err1
				}

				if !ordered {
					return false, errors.Errorf("cannot order by %v (type %T)", val, val)
				}
			}

			row.Key = append(row.Key, val)
		}

		t.Rows = append(t.Rows, row)
		return true, nil
	})
	if err != nil {
		return err
	}

	sort.Sort(t)

	var more bool
	for _, row := range t.Rows {
		if more, err = f(nil, row.Row); !more || err != nil {
			break
		}
	}
	return types.EOFAsNil(err)
}
Пример #2
0
func (r *OrderByDefaultPlan) fetchAll(ctx context.Context) error {
	evalArgs := map[interface{}]interface{}{}
	for {
		row, err := r.Src.Next(ctx)
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		evalArgs[expression.ExprEvalIdentReferFunc] = func(name string, scope int, index int) (interface{}, error) {
			if scope == expression.IdentReferFromTable {
				return row.FromData[index], nil
			} else if scope == expression.IdentReferSelectList {
				return row.Data[index], nil
			}

			// try to find in outer query
			return getIdentValueFromOuterQuery(ctx, name)
		}

		evalArgs[expression.ExprEvalPositionFunc] = func(position int) (interface{}, error) {
			// position is in [1, len(fields)], so we must decrease 1 to get correct index
			// TODO: check position invalidation
			return row.Data[position-1], nil
		}
		ordRow := &orderByRow{
			Row: row,
			Key: make([]interface{}, 0, len(r.By)),
		}
		for _, by := range r.By {
			// err1 is used for passing `go tool vet --shadow` check.
			val, err1 := by.Eval(ctx, evalArgs)
			if err1 != nil {
				return err1
			}

			if val != nil {
				if !types.IsOrderedType(val) {
					return errors.Errorf("cannot order by %v (type %T)", val, val)
				}
			}

			ordRow.Key = append(ordRow.Key, val)
		}
		r.ordTable.Rows = append(r.ordTable.Rows, ordRow)
	}
	sort.Sort(r.ordTable)
	return nil
}
Пример #3
0
func (r *OrderByDefaultPlan) fetchAll(ctx context.Context) error {
	evalArgs := map[interface{}]interface{}{}
	for {
		row, err := r.Src.Next(ctx)
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		evalArgs[expressions.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
			return getIdentValue(name, r.ResultFields, row.Data, field.CheckFieldFlag)
		}

		evalArgs[expressions.ExprEvalPositionFunc] = func(position int) (interface{}, error) {
			// position is in [1, len(fields)], so we must decrease 1 to get correct index
			// TODO: check position invalidation
			return row.Data[position-1], nil
		}
		ordRow := &orderByRow{
			Row: row,
			Key: make([]interface{}, 0, len(r.By)),
		}
		for _, by := range r.By {
			// err1 is used for passing `go tool vet --shadow` check.
			val, err1 := by.Eval(ctx, evalArgs)
			if err1 != nil {
				return err1
			}

			if val != nil {
				var ordered bool
				val, ordered, err1 = types.IsOrderedType(val)
				if err1 != nil {
					return err1
				}

				if !ordered {
					return errors.Errorf("cannot order by %v (type %T)", val, val)
				}
			}

			ordRow.Key = append(ordRow.Key, val)
		}
		r.ordTable.Rows = append(r.ordTable.Rows, ordRow)
	}
	sort.Sort(r.ordTable)
	return nil
}