예제 #1
0
func (*testResultFieldSuite) TestCheckWildcard(c *C) {
	// For CheckWildcardField
	t, w, err := field.CheckWildcardField("a")
	c.Assert(err, IsNil)
	c.Assert(t, Equals, "")
	c.Assert(w, IsFalse)

	t, w, err = field.CheckWildcardField("a.*")
	c.Assert(err, IsNil)
	c.Assert(t, Equals, "a")
	c.Assert(w, IsTrue)
}
예제 #2
0
파일: select_list.go 프로젝트: no2key/tidb
// ResolveSelectList gets fields and result fields from selectFields and srcFields,
// including field validity check and wildcard field processing.
func ResolveSelectList(selectFields []*field.Field, srcFields []*field.ResultField) (*SelectList, error) {
	selectList := &SelectList{
		Fields:       make([]*field.Field, 0, len(selectFields)),
		ResultFields: make([]*field.ResultField, 0, len(selectFields)),
		AggFields:    make(map[int]struct{}),
	}

	wildcardNum := 0
	for _, v := range selectFields {
		if err := expressions.CheckOneColumn(v.Expr); err != nil {
			return nil, errors.Trace(err)
		}

		// Check metioned field.
		names := expressions.MentionedColumns(v.Expr)
		if len(names) == 0 {
			selectList.AddField(v, nil)
			continue
		}

		// Check wildcard field.
		name := names[0]
		table, ok, err := field.CheckWildcardField(name)
		if err != nil {
			return nil, err
		}
		if ok {
			// Check unqualified wildcard field number,
			// like `select *, * from t`.
			if table == "" {
				wildcardNum++
				if wildcardNum > 1 {
					return nil, errors.Errorf("wildcard field exist more than once")
				}
			}

			selectList.updateFields(table, srcFields)
			continue
		}

		var result *field.ResultField
		if err = field.CheckAllFieldNames(names, srcFields, field.DefaultFieldFlag); err != nil {
			return nil, errors.Trace(err)
		}

		if _, ok := v.Expr.(*expressions.Ident); ok {
			// Field is ident.
			if result, err = field.CloneFieldByName(name, srcFields, field.DefaultFieldFlag); err != nil {
				return nil, errors.Trace(err)
			}

			// Maybe alias name or only column name.
			if !expressions.IsQualified(v.Name) {
				result.Name = v.Name
			}
		} else {
			// The field is not an ident, maybe binary expression,
			// like `select c1 + c2`, or `select c1 + 10`, etc.
			result = &field.ResultField{Name: v.Name}
		}

		selectList.AddField(v, result)
	}

	selectList.HiddenFieldOffset = len(selectList.Fields)
	selectList.resolveAggFields()

	if selectList.HiddenFieldOffset == 0 {
		return nil, errors.Errorf("invalid empty select fields")
	}

	return selectList, nil
}
예제 #3
0
파일: select_list.go 프로젝트: gaohf/tidb
// ResolveSelectList gets fields and result fields from selectFields and srcFields,
// including field validity check and wildcard field processing.
func ResolveSelectList(selectFields []*field.Field, srcFields []*field.ResultField) (*SelectList, error) {
	selectList := &SelectList{
		Fields:       make([]*field.Field, 0, len(selectFields)),
		ResultFields: make([]*field.ResultField, 0, len(selectFields)),
		AggFields:    make(map[int]struct{}),
		FromFields:   srcFields,
	}

	wildcardNum := 0
	for _, v := range selectFields {
		// Check metioned field.
		names := expression.MentionedColumns(v.Expr)
		if len(names) == 0 {
			selectList.AddField(v, nil)
			continue
		}

		// Check wildcard field.
		name := names[0]
		table, ok, err := field.CheckWildcardField(name)
		if err != nil {
			return nil, err
		}
		if ok {
			// Check unqualified wildcard field number,
			// like `select *, * from t`.
			if table == "" {
				wildcardNum++
				if wildcardNum > 1 {
					return nil, errors.Errorf("wildcard field exist more than once")
				}
			}

			selectList.updateFields(table, srcFields)
			continue
		}

		var result *field.ResultField
		for _, name := range names {
			idx := field.GetResultFieldIndex(name, srcFields, field.DefaultFieldFlag)
			if len(idx) > 1 {
				return nil, errors.Errorf("ambiguous field %s", name)
			}

			// TODO: must check in outer query too.
			if len(idx) == 0 {
				return nil, errors.Errorf("unknown field %s", name)
			}
		}

		if _, ok := v.Expr.(*expression.Ident); ok {
			// Field is ident.
			if result, err = field.CloneFieldByName(name, srcFields, field.DefaultFieldFlag); err != nil {
				return nil, errors.Trace(err)
			}

			// Use alias name
			if len(v.AsName) > 0 {
				result.Name = v.AsName
			} else {
				// use field identifier name directly, but not contain qualified name.
				// e.g, select t.c will only return c as the column name.
				s := v.Expr.String()
				n := strings.LastIndexByte(s, '.')
				if n == -1 {
					result.Name = s
				} else {
					result.Name = s[n+1:]
				}
			}
		}

		selectList.AddField(v, result)
	}

	selectList.HiddenFieldOffset = len(selectList.Fields)
	selectList.resolveAggFields()

	if selectList.HiddenFieldOffset == 0 {
		return nil, errors.Errorf("invalid empty select fields")
	}

	return selectList, nil
}