aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/sqlvm/checker/cast.go
blob: 40da20f81e38ce3f9074e56244c730ec78eb11a5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package checker

import (
    "fmt"

    "github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
    "github.com/dexon-foundation/dexon/core/vm/sqlvm/errors"
    "github.com/dexon-foundation/dexon/core/vm/sqlvm/schema"
)

func checkCastOperator(n *ast.CastOperatorNode,
    s schema.Schema, o CheckOptions, c *schemaCache, el *errors.ErrorList,
    tr schema.TableRef, ta typeAction) ast.ExprNode {

    fn := "CheckCastOperator"
    op := "operator CAST"

    hasError := false

    source := n.SourceExpr
    source = checkExpr(source, s, o, c, el, tr, nil)
    if source != nil {
        n.SourceExpr = source
    } else {
        hasError = true
    }
    target := n.TargetType
    dt, code, message := target.GetType()
    if code == errors.ErrorCodeNil {
        if !dt.ValidColumn() {
            el.Append(errors.Error{
                Position: target.GetPosition(),
                Length:   target.GetLength(),
                Category: errors.ErrorCategorySemantic,
                Code:     errors.ErrorCodeInvalidCastDataType,
                Severity: errors.ErrorSeverityError,
                Prefix:   fn,
                Message: fmt.Sprintf(
                    "cannot use %s with type %s", op, dt.String()),
            }, &hasError)
        }
    } else {
        el.Append(errors.Error{
            Position: target.GetPosition(),
            Length:   target.GetLength(),
            Category: errors.ErrorCategorySemantic,
            Code:     code,
            Severity: errors.ErrorSeverityError,
            Prefix:   fn,
            Message:  message,
        }, &hasError)
    }

    if hasError {
        return nil
    }
    r := ast.ExprNode(n)

    return verifyTypeAction(r, fn, dt, el, ta)
}