代码拉取完成,页面将自动刷新
同步操作将从 springrain/dm 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
* Copyright (c) 2000-2018, 达梦数据库有限公司.
* All rights reserved.
*/
package dm
import (
"bytes"
"strconv"
"strings"
"gitee.com/chunanyong/dm/util"
"gitee.com/chunanyong/dm/parser"
)
func (dc *DmConnection) lex(sql string) ([]*parser.LVal, error) {
if dc.lexer == nil {
dc.lexer = parser.NewLexer(strings.NewReader(sql), false)
} else {
dc.lexer.Reset(strings.NewReader(sql))
}
lexer := dc.lexer
var lval *parser.LVal
var err error
lvalList := make([]*parser.LVal, 0, 64)
lval, err = lexer.Yylex()
if err != nil {
return nil, err
}
for lval != nil {
lvalList = append(lvalList, lval)
lval.Position = len(lvalList)
lval, err = lexer.Yylex()
if err != nil {
return nil, err
}
}
return lvalList, nil
}
func lexSkipWhitespace(sql string, n int) ([]*parser.LVal, error) {
lexer := parser.NewLexer(strings.NewReader(sql), false)
var lval *parser.LVal
var err error
lvalList := make([]*parser.LVal, 0, 64)
lval, err = lexer.Yylex()
if err != nil {
return nil, err
}
for lval != nil && n > 0 {
lval.Position = len(lvalList)
if lval.Tp == parser.WHITESPACE_OR_COMMENT {
continue
}
lvalList = append(lvalList, lval)
n--
lval, err = lexer.Yylex()
if err != nil {
return nil, err
}
}
return lvalList, nil
}
func (dc *DmConnection) escape(sql string, keywords []string) (string, error) {
if (keywords == nil || len(keywords) == 0) && strings.Index(sql, "{") == -1 {
return sql, nil
}
var keywordMap map[string]interface{}
if keywords != nil && len(keywords) > 0 {
keywordMap = make(map[string]interface{}, len(keywords))
for _, keyword := range keywords {
keywordMap[strings.ToUpper(keyword)] = nil
}
}
nsql := bytes.NewBufferString("")
stack := make([]bool, 0, 64)
lvalList, err := dc.lex(sql)
if err != nil {
return "", err
}
for i := 0; i < len(lvalList); i++ {
lval0 := lvalList[i]
if lval0.Tp == parser.NORMAL {
if lval0.Value == "{" {
lval1 := next(lvalList, i+1)
if lval1 == nil || lval1.Tp != parser.NORMAL {
stack = append(stack, false)
nsql.WriteString(lval0.Value)
} else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "escape") || util.StringUtil.EqualsIgnoreCase(lval1.Value, "call") {
stack = append(stack, true)
} else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "oj") {
stack = append(stack, true)
lval1.Value = ""
lval1.Tp = parser.WHITESPACE_OR_COMMENT
} else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "d") {
stack = append(stack, true)
lval1.Value = "date"
} else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "t") {
stack = append(stack, true)
lval1.Value = "time"
} else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "ts") {
stack = append(stack, true)
lval1.Value = "datetime"
} else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "fn") {
stack = append(stack, true)
lval1.Value = ""
lval1.Tp = parser.WHITESPACE_OR_COMMENT
lval2 := next(lvalList, lval1.Position+1)
if lval2 != nil && lval2.Tp == parser.NORMAL && util.StringUtil.EqualsIgnoreCase(lval2.Value, "database") {
lval2.Value = "cur_database"
}
} else if util.StringUtil.Equals(lval1.Value, "?") {
lval2 := next(lvalList, lval1.Position+1)
if lval2 != nil && lval2.Tp == parser.NORMAL && util.StringUtil.EqualsIgnoreCase(lval2.Value, "=") {
lval3 := next(lvalList, lval2.Position+1)
if lval3 != nil && lval3.Tp == parser.NORMAL && util.StringUtil.EqualsIgnoreCase(lval3.Value, "call") {
stack = append(stack, true)
lval3.Value = ""
lval3.Tp = parser.WHITESPACE_OR_COMMENT
} else {
stack = append(stack, false)
nsql.WriteString(lval0.Value)
}
} else {
stack = append(stack, false)
nsql.WriteString(lval0.Value)
}
} else {
stack = append(stack, false)
nsql.WriteString(lval0.Value)
}
} else if util.StringUtil.Equals(lval0.Value, "}") {
if len(stack) != 0 && stack[len(stack)-1] {
} else {
nsql.WriteString(lval0.Value)
}
stack = stack[:len(stack)-1]
} else {
if keywordMap != nil {
_, ok := keywordMap[strings.ToUpper(lval0.Value)]
if ok {
nsql.WriteString("\"" + util.StringUtil.ProcessDoubleQuoteOfName(strings.ToUpper(lval0.Value)) + "\"")
} else {
nsql.WriteString(lval0.Value)
}
} else {
nsql.WriteString(lval0.Value)
}
}
} else if lval0.Tp == parser.STRING {
nsql.WriteString("'" + util.StringUtil.ProcessSingleQuoteOfName(lval0.Value) + "'")
} else {
nsql.WriteString(lval0.Value)
}
}
return nsql.String(), nil
}
func next(lvalList []*parser.LVal, start int) *parser.LVal {
var lval *parser.LVal
size := len(lvalList)
for i := start; i < size; i++ {
lval = lvalList[i]
if lval.Tp != parser.WHITESPACE_OR_COMMENT {
break
}
}
return lval
}
func (dc *DmConnection) execOpt(sql string, optParamList []OptParameter, serverEncoding string) (string, []OptParameter, error) {
nsql := bytes.NewBufferString("")
lvalList, err := dc.lex(sql)
if err != nil {
return "", optParamList, err
}
if nil == lvalList || len(lvalList) == 0 {
return sql, optParamList, nil
}
firstWord := lvalList[0].Value
if !(util.StringUtil.EqualsIgnoreCase(firstWord, "INSERT") || util.StringUtil.EqualsIgnoreCase(firstWord, "SELECT") ||
util.StringUtil.EqualsIgnoreCase(firstWord, "UPDATE") || util.StringUtil.EqualsIgnoreCase(firstWord, "DELETE")) {
return sql, optParamList, nil
}
breakIndex := 0
for i := 0; i < len(lvalList); i++ {
lval := lvalList[i]
switch lval.Tp {
case parser.NULL:
{
nsql.WriteString("?")
optParamList = append(optParamList, newOptParameter(nil, NULL, NULL_PREC))
}
case parser.INT:
{
nsql.WriteString("?")
value, err := strconv.Atoi(lval.Value)
if err != nil {
return "", optParamList, err
}
if value <= int(INT32_MAX) && value >= int(INT32_MIN) {
optParamList = append(optParamList, newOptParameter(G2DB.toInt32(int32(value)), INT, INT_PREC))
} else {
optParamList = append(optParamList, newOptParameter(G2DB.toInt64(int64(value)), BIGINT, BIGINT_PREC))
}
}
case parser.DOUBLE:
{
nsql.WriteString("?")
f, err := strconv.ParseFloat(lval.Value, 64)
if err != nil {
return "", optParamList, err
}
optParamList = append(optParamList, newOptParameter(G2DB.toFloat64(f), DOUBLE, DOUBLE_PREC))
}
case parser.DECIMAL:
{
nsql.WriteString("?")
bytes, err := G2DB.toDecimal(lval.Value, 0, 0)
if err != nil {
return "", optParamList, err
}
optParamList = append(optParamList, newOptParameter(bytes, DECIMAL, 0))
}
case parser.STRING:
{
if len(lval.Value) > int(INT16_MAX) {
nsql.WriteString("'" + util.StringUtil.ProcessSingleQuoteOfName(lval.Value) + "'")
} else {
nsql.WriteString("?")
optParamList = append(optParamList, newOptParameter(Dm_build_1298.Dm_build_1511(lval.Value, serverEncoding, dc), VARCHAR, VARCHAR_PREC))
}
}
case parser.HEX_INT:
nsql.WriteString(lval.Value)
default:
nsql.WriteString(lval.Value)
}
if breakIndex > 0 {
break
}
}
if breakIndex > 0 {
for i := breakIndex + 1; i < len(lvalList); i++ {
nsql.WriteString(lvalList[i].Value)
}
}
return nsql.String(), optParamList, nil
}
func (dc *DmConnection) hasConst(sql string) (bool, error) {
lvalList, err := dc.lex(sql)
if err != nil {
return false, err
}
if nil == lvalList || len(lvalList) == 0 {
return false, nil
}
for i := 0; i < len(lvalList); i++ {
switch lvalList[i].Tp {
case parser.NULL, parser.INT, parser.DOUBLE, parser.DECIMAL, parser.STRING, parser.HEX_INT:
return true, nil
}
}
return false, nil
}
type OptParameter struct {
bytes []byte
ioType byte
tp int
prec int
scale int
}
func newOptParameter(bytes []byte, tp int, prec int) OptParameter {
o := new(OptParameter)
o.bytes = bytes
o.tp = tp
o.prec = prec
return *o
}
func (parameter *OptParameter) String() string {
if parameter.bytes == nil {
return ""
}
return string(parameter.bytes)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。