예제 #1
0
// Select selects rows from a single table. Select is the workhorse of the SQL
// statements. In the slowest and most general case, select must perform full
// table scans across multiple tables and sort and join the resulting rows on
// arbitrary columns. Full table scans can be avoided when indexes can be used
// to satisfy the where-clause.
//
// Privileges: SELECT on table
//   Notes: postgres requires SELECT. Also requires UPDATE on "FOR UPDATE".
//          mysql requires SELECT.
func (p *planner) Select(n *parser.Select) (planNode, error) {
	scan := &scanNode{txn: p.txn}
	if err := scan.initFrom(p, n.From); err != nil {
		return nil, err
	}
	if err := scan.initWhere(n.Where); err != nil {
		return nil, err
	}
	if err := scan.initTargets(n.Exprs); err != nil {
		return nil, err
	}
	group, err := p.groupBy(n, scan)
	if err != nil {
		return nil, err
	}
	if group != nil && n.OrderBy != nil {
		// TODO(pmattis): orderBy currently uses deep knowledge of the
		// scanNode. Need to lift that out or make orderBy compatible with
		// groupNode as well.
		return nil, fmt.Errorf("TODO(pmattis): unimplemented ORDER BY with GROUP BY/aggregation")
	}
	sort, err := p.orderBy(n, scan)
	if err != nil {
		return nil, err
	}
	// TODO(pmattis): Consider aggregation functions during index
	// selection. Specifically, MIN(k) and MAX(k) where k is the first column in
	// an index can be satisfied with a single read.
	plan, err := p.selectIndex(scan, sort.Ordering())
	if err != nil {
		return nil, err
	}
	return sort.wrap(group.wrap(plan)), nil
}
예제 #2
0
파일: select.go 프로젝트: surpass/cockroach
func (p *planner) initSelect(s *selectNode, parsed *parser.Select) (planNode, *roachpb.Error) {
	if pErr := s.initFrom(p, parsed); pErr != nil {
		return nil, pErr
	}

	// TODO(radu): for now we assume from is always a scanNode
	scan := s.from.(*scanNode)

	// NB: both orderBy and groupBy are passed and can modify `scan` but orderBy must do so first.
	sort, pErr := p.orderBy(parsed, scan)
	if pErr != nil {
		return nil, pErr
	}
	group, pErr := p.groupBy(parsed, scan)
	if pErr != nil {
		return nil, pErr
	}

	if scan.filter != nil && group != nil {
		// Allow the group-by to add an implicit "IS NOT NULL" filter.
		scan.filter = group.isNotNullFilter(scan.filter)
	}

	// Get the ordering for index selection (if any).
	var ordering []int
	var grouping bool

	if group != nil {
		ordering = group.desiredOrdering
		grouping = true
	} else if sort != nil {
		ordering, _ = sort.Ordering()
	}

	plan, pErr := p.selectIndex(scan, ordering, grouping)
	if pErr != nil {
		return nil, pErr
	}

	// Update s.from with the new plan.
	s.from = plan

	// Wrap this node as necessary.
	limit, pErr := p.limit(parsed, p.distinct(parsed, sort.wrap(group.wrap(s))))
	if pErr != nil {
		return nil, pErr
	}
	return limit, nil
}
예제 #3
0
// Select selects rows from a single table. Select is the workhorse of the SQL
// statements. In the slowest and most general case, select must perform full
// table scans across multiple tables and sort and join the resulting rows on
// arbitrary columns. Full table scans can be avoided when indexes can be used
// to satisfy the where-clause.
//
// Privileges: SELECT on table
//   Notes: postgres requires SELECT. Also requires UPDATE on "FOR UPDATE".
//          mysql requires SELECT.
func (p *planner) Select(n *parser.Select) (planNode, error) {
	scan := &scanNode{planner: p, txn: p.txn}
	if err := scan.initFrom(p, n.From); err != nil {
		return nil, err
	}
	if err := scan.initWhere(n.Where); err != nil {
		return nil, err
	}
	if err := scan.initTargets(n.Exprs); err != nil {
		return nil, err
	}
	group, err := p.groupBy(n, scan)
	if err != nil {
		return nil, err
	}
	if group != nil && n.OrderBy != nil {
		// TODO(pmattis): orderBy currently uses deep knowledge of the
		// scanNode. Need to lift that out or make orderBy compatible with
		// groupNode as well.
		return nil, util.Errorf("TODO(pmattis): unimplemented ORDER BY with GROUP BY/aggregation")
	}
	sort, err := p.orderBy(n, scan)
	if err != nil {
		return nil, err
	}

	var ordering []int
	if group != nil {
		ordering = group.desiredOrdering
	} else if sort != nil {
		ordering, _ = sort.Ordering()
	}
	plan, err := p.selectIndex(scan, ordering)
	if err != nil {
		return nil, err
	}

	limit, err := p.limit(n, p.distinct(n, sort.wrap(group.wrap(plan))))
	if err != nil {
		return nil, err
	}
	return limit, nil
}
예제 #4
0
// Select selects rows from a single table. Select is the workhorse of the SQL
// statements. In the slowest and most general case, select must perform full
// table scans across multiple tables and sort and join the resulting rows on
// arbitrary columns. Full table scans can be avoided when indexes can be used
// to satisfy the where-clause.
//
// Privileges: SELECT on table
//   Notes: postgres requires SELECT. Also requires UPDATE on "FOR UPDATE".
//          mysql requires SELECT.
func (p *planner) Select(n *parser.Select) (planNode, error) {
	scan := &scanNode{txn: p.txn}
	if err := scan.initFrom(p, n.From); err != nil {
		return nil, err
	}
	if err := scan.initWhere(n.Where); err != nil {
		return nil, err
	}
	if err := scan.initTargets(n.Exprs); err != nil {
		return nil, err
	}
	sort, err := p.orderBy(n, scan)
	if err != nil {
		return nil, err
	}
	plan, err := p.selectIndex(scan, sort.Ordering())
	if err != nil {
		return nil, err
	}
	return sort.wrap(plan), nil
}