Esempio n. 1
0
func parseAndNormalizeExpr(t *testing.T, sql string) (parser.Expr, qvalMap) {
	q, err := parser.ParseTraditional("SELECT " + sql)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	expr := q[0].(*parser.Select).Exprs[0].Expr
	r, err := parser.NormalizeExpr(expr)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}

	// Perform qualified name resolution because {analyze,simplify}Expr want
	// expressions containing qvalues.
	s := &scanNode{}
	s.desc = &TableDescriptor{
		Columns: []ColumnDescriptor{
			{Name: "a", ID: 1, Type: ColumnType{Kind: ColumnType_INT}},
			{Name: "b", ID: 2, Type: ColumnType{Kind: ColumnType_INT}},
			{Name: "c", ID: 3, Type: ColumnType{Kind: ColumnType_INT}},
			{Name: "d", ID: 4, Type: ColumnType{Kind: ColumnType_INT}},
			{Name: "e", ID: 5, Type: ColumnType{Kind: ColumnType_INT}},
		},
	}
	s.visibleCols = s.desc.Columns

	r, err = s.resolveQNames(r)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	return r, s.qvals
}
Esempio n. 2
0
func parseAndNormalizeExpr(t *testing.T, sql string) (parser.Expr, qvalMap) {
	q, err := parser.ParseTraditional("SELECT " + sql)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	expr := q[0].(*parser.Select).Exprs[0].Expr
	expr, err = parser.NormalizeExpr(expr)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}

	// Perform qualified name resolution because {analyze,simplify}Expr want
	// expressions containing qvalues.
	s := &scanNode{}
	s.desc = testTableDesc()
	s.visibleCols = s.desc.Columns

	if err := s.desc.AllocateIDs(); err != nil {
		t.Fatal(err)
	}

	expr, err = s.resolveQNames(expr)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	if _, err := parser.TypeCheckExpr(expr); err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	return expr, s.qvals
}
Esempio n. 3
0
func (n *scanNode) initWhere(where *parser.Where) error {
	if where == nil {
		return nil
	}
	n.filter, n.err = n.resolveQNames(where.Expr)
	if n.err == nil {
		// Normalize the expression (this will also evaluate any branches that are
		// constant).
		n.filter, n.err = parser.NormalizeExpr(n.filter)
	}
	return n.err
}
Esempio n. 4
0
// limit constructs a limitNode based on the LIMIT and OFFSET clauses.
func (*planner) limit(n *parser.Select, p planNode) (planNode, error) {
	if n.Limit == nil {
		return p, nil
	}

	var count, offset int64

	data := []struct {
		name       string
		src        parser.Expr
		dst        *int64
		defaultVal int64
	}{
		{"LIMIT", n.Limit.Count, &count, math.MaxInt64},
		{"OFFSET", n.Limit.Offset, &offset, 0},
	}

	for _, datum := range data {
		if datum.src == nil {
			*datum.dst = datum.defaultVal
		} else {
			if parser.ContainsVars(datum.src) {
				return nil, fmt.Errorf("argument of %s must not contain variables", datum.name)
			}

			normalized, err := parser.NormalizeExpr(datum.src)
			if err != nil {
				return nil, err
			}
			dstDatum, err := parser.EvalExpr(normalized)
			if err != nil {
				return nil, err
			}

			if dstDatum == parser.DNull {
				*datum.dst = datum.defaultVal
				continue
			}

			if dstDInt, ok := dstDatum.(parser.DInt); ok {
				*datum.dst = int64(dstDInt)
				continue
			}

			return nil, fmt.Errorf("argument of %s must be type %s, not type %s", datum.name, parser.DummyInt.Type(), dstDatum.Type())
		}
	}

	return &limitNode{planNode: p, count: count, offset: offset}, nil
}
Esempio n. 5
0
func (n *scanNode) initWhere(where *parser.Where) error {
	if where == nil {
		return nil
	}
	n.filter, n.err = n.resolveQNames(where.Expr)
	if n.err == nil {
		// Normalize the expression (this will also evaluate any branches that are
		// constant).
		n.filter, n.err = parser.NormalizeExpr(n.filter)
	}
	if n.err == nil {
		var whereType parser.Datum
		whereType, n.err = parser.TypeCheckExpr(n.filter)
		if n.err == nil {
			if !(whereType == parser.DummyBool || whereType == parser.DNull) {
				n.err = fmt.Errorf("argument of WHERE must be type %s, not type %s", parser.DummyBool.Type(), whereType.Type())
			}
		}
	}
	return n.err
}
Esempio n. 6
0
func makeDefaultExprs(cols []ColumnDescriptor) ([]parser.Expr, error) {
	// Check to see if any of the columns have DEFAULT expressions. If there are
	// no DEFAULT expressions, we don't bother with constructing the defaults map
	// as the defaults are all NULL.
	haveDefaults := false
	for _, col := range cols {
		if col.DefaultExpr != nil {
			haveDefaults = true
			break
		}
	}
	if !haveDefaults {
		return nil, nil
	}

	// Build the default expressions map from the parsed SELECT statement.
	defaultExprs := make([]parser.Expr, 0, len(cols))
	for _, col := range cols {
		if col.DefaultExpr == nil {
			defaultExprs = append(defaultExprs, parser.DNull)
			continue
		}
		expr, err := parser.ParseExpr(*col.DefaultExpr, parser.Traditional)
		if err != nil {
			return nil, err
		}
		expr, err = parser.NormalizeExpr(expr)
		if err != nil {
			return nil, err
		}
		if parser.ContainsVars(expr) {
			return nil, util.Errorf("default expression contains variables")
		}
		defaultExprs = append(defaultExprs, expr)
	}
	return defaultExprs, nil
}
Esempio n. 7
0
// orderBy constructs a sortNode based on the ORDER BY clause. Construction of
// the sortNode might adjust the number of render targets in the scanNode if
// any ordering expressions are specified.
func (p *planner) orderBy(n *parser.Select, s *scanNode) (*sortNode, error) {
	if n.OrderBy == nil {
		return nil, nil
	}

	// We grab a copy of columns here because we might add new render targets
	// below. This is the set of columns requested by the query.
	columns := s.Columns()
	var ordering []int

	for _, o := range n.OrderBy {
		index := 0

		// Normalize the expression which has the side-effect of evaluating
		// constant expressions and unwrapping expressions like "((a))" to "a".
		expr, err := parser.NormalizeExpr(o.Expr)
		if err != nil {
			return nil, err
		}

		if qname, ok := expr.(*parser.QualifiedName); ok {
			if len(qname.Indirect) == 0 {
				// Look for an output column that matches the qualified name. This
				// handles cases like:
				//
				//   SELECT a AS b FROM t ORDER BY b
				target := string(qname.Base)
				for j, col := range columns {
					if equalName(target, col) {
						index = j + 1
						break
					}
				}
			}

			if index == 0 {
				// No output column matched the qualified name, so look for an existing
				// render target that matches the column name. This handles cases like:
				//
				//   SELECT a AS b FROM t ORDER BY a
				if err := qname.NormalizeColumnName(); err != nil {
					return nil, err
				}
				if qname.Table() == "" || equalName(s.desc.Alias, qname.Table()) {
					for j, r := range s.render {
						if qval, ok := r.(*qvalue); ok {
							if equalName(qval.col.Name, qname.Column()) {
								index = j + 1
								break
							}
						}
					}
				}
			}
		}

		if index == 0 {
			// The order by expression matched neither an output column nor an
			// existing render target.
			if datum, ok := expr.(parser.Datum); ok {
				// If we evaluated to an int, use that as an index to order by. This
				// handles cases like:
				//
				//   SELECT * FROM t ORDER BY 1
				i, ok := datum.(parser.DInt)
				if !ok {
					return nil, fmt.Errorf("invalid ORDER BY: %s", expr)
				}
				index = int(i)
				if index < 1 || index > len(columns) {
					return nil, fmt.Errorf("invalid ORDER BY index: %d not in range [1, %d]",
						index, len(columns))
				}
			} else {
				// Add a new render expression to use for ordering. This handles cases
				// were the expression is either not a qualified name or is a qualified
				// name that is otherwise not referenced by the query:
				//
				//   SELECT a FROM t ORDER by b
				//   SELECT a, b FROM t ORDER by a+b
				if err := s.addRender(parser.SelectExpr{Expr: expr}); err != nil {
					return nil, err
				}
				index = len(s.columns)
			}
		}

		if o.Direction == parser.Descending {
			index = -index
		}
		ordering = append(ordering, index)
	}

	return &sortNode{columns: columns, ordering: ordering}, nil
}