예제 #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
	expr, err = (parser.EvalContext{}).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
}
예제 #2
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
}
예제 #3
0
func makeColumnDefDescs(d *parser.ColumnTableDef) (*ColumnDescriptor, *IndexDescriptor, error) {
	col := &ColumnDescriptor{
		Name:     string(d.Name),
		Nullable: (d.Nullable != parser.NotNull),
	}

	var colDatumType parser.Datum
	switch t := d.Type.(type) {
	case *parser.BoolType:
		col.Type.Kind = ColumnType_BOOL
		colDatumType = parser.DummyBool
	case *parser.IntType:
		col.Type.Kind = ColumnType_INT
		col.Type.Width = int32(t.N)
		colDatumType = parser.DummyInt
	case *parser.FloatType:
		col.Type.Kind = ColumnType_FLOAT
		col.Type.Precision = int32(t.Prec)
		colDatumType = parser.DummyFloat
	case *parser.DecimalType:
		col.Type.Kind = ColumnType_DECIMAL
		col.Type.Width = int32(t.Scale)
		col.Type.Precision = int32(t.Prec)
	case *parser.DateType:
		col.Type.Kind = ColumnType_DATE
		colDatumType = parser.DummyDate
	case *parser.TimestampType:
		col.Type.Kind = ColumnType_TIMESTAMP
		colDatumType = parser.DummyTimestamp
	case *parser.IntervalType:
		col.Type.Kind = ColumnType_INTERVAL
		colDatumType = parser.DummyInterval
	case *parser.StringType:
		col.Type.Kind = ColumnType_STRING
		col.Type.Width = int32(t.N)
		colDatumType = parser.DummyString
	case *parser.BytesType:
		col.Type.Kind = ColumnType_BYTES
		colDatumType = parser.DummyBytes
	default:
		return nil, nil, util.Errorf("unexpected type %T", t)
	}

	if d.DefaultExpr != nil {
		// Verify the default expression type is compatible with the column type.
		defaultType, err := parser.TypeCheckExpr(d.DefaultExpr)
		if err != nil {
			return nil, nil, err
		}
		if colDatumType != defaultType {
			return nil, nil, fmt.Errorf("incompatible column type and default expression: %s vs %s",
				col.Type.Kind, defaultType.Type())
		}

		s := d.DefaultExpr.String()
		col.DefaultExpr = &s
	}

	var idx *IndexDescriptor
	if d.PrimaryKey || d.Unique {
		idx = &IndexDescriptor{
			Unique:      true,
			ColumnNames: []string{string(d.Name)},
		}
	}

	return col, idx, nil
}