aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/vm/sqlvm/checker/cast.go60
-rw-r--r--core/vm/sqlvm/checker/expr.go2
-rw-r--r--core/vm/sqlvm/errors/errors.go2
3 files changed, 63 insertions, 1 deletions
diff --git a/core/vm/sqlvm/checker/cast.go b/core/vm/sqlvm/checker/cast.go
new file mode 100644
index 000000000..40da20f81
--- /dev/null
+++ b/core/vm/sqlvm/checker/cast.go
@@ -0,0 +1,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)
+}
diff --git a/core/vm/sqlvm/checker/expr.go b/core/vm/sqlvm/checker/expr.go
index d62f82ede..e31a13d62 100644
--- a/core/vm/sqlvm/checker/expr.go
+++ b/core/vm/sqlvm/checker/expr.go
@@ -138,7 +138,7 @@ func checkExpr(n ast.ExprNode,
return checkLikeOperator(n, s, o, c, el, tr, ta)
case *ast.CastOperatorNode:
- return n
+ return checkCastOperator(n, s, o, c, el, tr, ta)
case *ast.InOperatorNode:
return checkInOperator(n, s, o, c, el, tr, ta)
diff --git a/core/vm/sqlvm/errors/errors.go b/core/vm/sqlvm/errors/errors.go
index dcc8e6a48..2bbac5b4b 100644
--- a/core/vm/sqlvm/errors/errors.go
+++ b/core/vm/sqlvm/errors/errors.go
@@ -170,6 +170,7 @@ const (
ErrorCodeConstantTooLong
ErrorCodeNonConstantExpression
ErrorCodeInvalidAddressChecksum
+ ErrorCodeInvalidCastDataType
// Runtime Error
ErrorCodeInvalidOperandNum
@@ -229,6 +230,7 @@ var errorCodeMap = [...]string{
ErrorCodeConstantTooLong: "constant too long",
ErrorCodeNonConstantExpression: "non-constant expression",
ErrorCodeInvalidAddressChecksum: "invalid address checksum",
+ ErrorCodeInvalidCastDataType: "invalid cast data type",
// Runtime Error
ErrorCodeInvalidOperandNum: "invalid operand number",