func Analyze(s parser.SelectStmt, reg udf.FunctionRegistry) (*LogicalPlan, error) {
	if err := makeRelationAliases(&s); err != nil {
		return nil, err
	}
	if err := validateReferences(&s); err != nil {
		return nil, err
	}
	return flattenExpressions(&s, reg)
}
Analyze checks the given SELECT statement for logical errors
(references to unknown tables etc.) and creates a LogicalPlan
that is internally consistent.
package execution
import (
	"fmt"
	"math"
	"regexp"
	"strings"
	"gopkg.in/sensorbee/sensorbee.v0/bql/parser"
	"gopkg.in/sensorbee/sensorbee.v0/bql/udf"
	"gopkg.in/sensorbee/sensorbee.v0/core"
	"gopkg.in/sensorbee/sensorbee.v0/data"
)
const (
	MaxRangeTuples   float64 = 1<<20 - 1
	MaxRangeSec      float64 = 60 * 60 * 24
	MaxRangeMillisec float64 = 60 * 60 * 24 * 1000
)
var (
	simpleColumnNameRe = regexp.MustCompile("^[a-z][a-zA-Z0-9_]*$")
)
type LogicalPlan struct {
	GroupingStmt        bool
	EmitterType         parser.Emitter
	EmitterLimit        int64
	EmitterSampling     float64
	EmitterSamplingType parser.EmitterSamplingType
	Projections         []aliasedExpression
	parser.WindowedFromAST
	Filter    FlatExpression
	GroupList []FlatExpression
	parser.HavingAST
}
type PhysicalPlan interface {
	Process(input *core.Tuple) ([]data.Map, error)
}