Ejemplo n.º 1
0
// nextRow processes table rows until it finds a row that passes the filter.
// Returns a nil row when there are no more rows.
func (tr *tableReader) nextRow() (sqlbase.EncDatumRow, error) {
	for {
		fetcherRow, err := tr.fetcher.NextRow()
		if err != nil || fetcherRow == nil {
			return nil, err
		}

		// TODO(radu): we are defeating the purpose of EncDatum here - we
		// should modify RowFetcher to return EncDatums directly and avoid
		// the cost of decoding/reencoding.
		for i := range fetcherRow {
			if fetcherRow[i] != nil {
				tr.row[i].SetDatum(tr.desc.Columns[i].Type.Kind, fetcherRow[i])
			}
		}
		passesFilter, err := sqlbase.RunFilter(tr.filter, tr.evalCtx)
		if err != nil {
			return nil, err
		}
		if passesFilter {
			break
		}
	}
	// TODO(radu): investigate removing this allocation. We can't reuse the
	// same slice because it is being read asynchronously on the other side
	// of the channel. Perhaps streamMsg can store a few preallocated
	// elements to avoid allocation in most cases.
	outRow := make(sqlbase.EncDatumRow, len(tr.outputCols))
	for i, col := range tr.outputCols {
		outRow[i] = tr.row[col]
	}
	return outRow, nil
}
Ejemplo n.º 2
0
func (n *scanNode) Next() (bool, error) {
	tracing.AnnotateTrace()
	if !n.scanInitialized {
		if err := n.initScan(); err != nil {
			return false, nil
		}
	}

	if n.explain == explainDebug {
		return n.debugNext()
	}

	// We fetch one row at a time until we find one that passes the filter.
	for {
		var err error
		n.row, err = n.fetcher.NextRow()
		if err != nil || n.row == nil {
			return false, err
		}
		passesFilter, err := sqlbase.RunFilter(n.filter, n.p.evalCtx)
		if err != nil {
			return false, err
		}
		if passesFilter {
			return true, nil
		}
	}
}
Ejemplo n.º 3
0
// debugNext is a helper function used by Next() when in explainDebug mode.
func (n *scanNode) debugNext() (bool, error) {
	// In debug mode, we output a set of debug values for each key.
	n.debugVals.rowIdx = n.rowIndex
	var err error
	n.debugVals.key, n.debugVals.value, n.row, err = n.fetcher.NextKeyDebug()
	if err != nil || n.debugVals.key == "" {
		return false, err
	}

	if n.row != nil {
		passesFilter, err := sqlbase.RunFilter(n.filter, n.p.evalCtx)
		if err != nil {
			return false, err
		}
		if passesFilter {
			n.debugVals.output = debugValueRow
		} else {
			n.debugVals.output = debugValueFiltered
		}
		n.rowIndex++
	} else {
		n.debugVals.output = debugValuePartial
	}
	return true, nil
}
Ejemplo n.º 4
0
func (s *selectNode) Next() (bool, error) {
	for {
		if next, err := s.source.plan.Next(); !next {
			return false, err
		}

		if s.explain == explainDebug {
			s.debugVals = s.source.plan.DebugValues()

			if s.debugVals.output != debugValueRow {
				// Let the debug values pass through.
				return true, nil
			}
		}
		row := s.source.plan.Values()
		s.qvals.populateQVals(&s.source.info, row)
		passesFilter, err := sqlbase.RunFilter(s.filter, &s.planner.evalCtx)
		if err != nil {
			return false, err
		}

		if passesFilter {
			err := s.renderRow()
			return err == nil, err
		} else if s.explain == explainDebug {
			// Mark the row as filtered out.
			s.debugVals.output = debugValueFiltered
			return true, nil
		}
		// Row was filtered out; grab the next row.
	}
}
Ejemplo n.º 5
0
// evalFilter is used for filter expressions; it evaluates the expression and
// returns whether the filter passes.
func (eh *exprHelper) evalFilter(row sqlbase.EncDatumRow) (bool, error) {
	eh.row = row
	return sqlbase.RunFilter(eh.expr, eh.evalCtx)
}