wecisecode 2 дней назад
Родитель
Сommit
e9b74710e5

+ 4 - 4
odbctest/mql/0/0.mql

@@ -1,12 +1,12 @@
 
 
 
-
-MATCH (:/matrix/oo/automobile/)-[*]->(:/matrix/oo/ where brand = '普利司通' or brand = '立中车轮')
+SELECT id, prom.date('2024-11-28').avg().sigma() FROM  /test/bucketpromdb
 /**
 output()
-match("graph.nodes.len", 65)
-match("graph.edges.len", 60)
+matchcount(id, "bucketpromdb:wecise11", "prom.0.2", 2.661111111111112, 1)
+matchcount(id, "bucketpromdb:wecise", "prom.0.5", 0.15630781478860528~0.1563078147886053, 1)
 **/
 ;
 
+

+ 1 - 1
odbctest/mql/basic/24bucket_promdb/1040valid.mql

@@ -314,6 +314,6 @@ SELECT id, prom.date('2024-11-28').avg().sigma() FROM  /test/bucketpromdb
 /**
 output()
 matchcount(id, "bucketpromdb:wecise11", "prom.0.2", 2.661111111111112, 1)
-matchcount(id, "bucketpromdb:wecise", "prom.0.5", 0.15630781478860528, 1)
+matchcount(id, "bucketpromdb:wecise", "prom.0.5", 0.15630781478860528~0.1563078147886053, 1)
 **/
 ;

+ 6 - 106
odbctest/odbcmql/mqls_do.go

@@ -351,30 +351,6 @@ func (mt *MQLTest) RunMQLTryOnce(t *testing.T, ctx context.Context,
 	return
 }
 
-func matchvalue(matcher any, matchingvalue any) (bool, string) {
-	switch m := matcher.(type) {
-	case *regexp.Regexp:
-		switch v := matchingvalue.(type) {
-		case string:
-			return m.MatchString(v), v
-		default:
-			sv := fmt.Sprintf("%#v", matchingvalue)
-			return m.MatchString(sv), sv
-		}
-	case string:
-		sv := ""
-		switch matchingvalue.(type) {
-		case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, float32, float64, bool:
-			sv = fmt.Sprintf("%v", matchingvalue)
-		default:
-			sv = fmt.Sprintf("%#v", matchingvalue)
-		}
-		return sv == m, sv
-	default:
-		panic("未定义的匹配类型")
-	}
-}
-
 func (mt *MQLTest) doFollowThroughActions(t *testing.T, testname string, toption *OnErrorOption, rtn *odb.Result, actions []*Action, mql string) (seriouserror bool, err error) {
 	if len(actions) > 0 {
 		if rtn == nil {
@@ -553,6 +529,11 @@ func (mt *MQLTest) doFollowThroughActions(t *testing.T, testname string, toption
 							}
 							m = r
 						}
+					case *Action:
+						switch arg.Name {
+						case "<FUZZY>":
+							m = arg
+						}
 					}
 					if m == nil {
 						m = fmt.Sprintf("%#v", args[i+1])
@@ -573,88 +554,7 @@ func (mt *MQLTest) doFollowThroughActions(t *testing.T, testname string, toption
 					seriouserror = true
 					return
 				}
-				x := 0
-				var matchingvalues [][]any
-				var matchingvalue any
-				for _, dat := range rtn.Data {
-					matchingvalues = append(matchingvalues, []any{})
-					m := false
-					sv := ""
-					match := true
-					for i, k := range ks {
-						matchingvalue = dat[k]
-						m, sv = matchvalue(ms[i], matchingvalue)
-						if !m {
-							ks := strings.Split(k, ".")
-							if len(ks) <= 1 {
-								match = false
-								break
-							} else {
-								k := ""
-								for i := 0; match && i < len(ks); i++ {
-									if matchingvalue == nil {
-										if k != "" {
-											k += "."
-										}
-										k += ks[i]
-										matchingvalue = dat[k]
-										if matchingvalue == nil && ks[i] == "len" {
-											matchingvalue = 0
-										}
-									} else {
-										switch mv := matchingvalue.(type) {
-										case map[string]interface{}:
-											matchingvalue = mv[ks[i]]
-											if matchingvalue == nil && ks[i] == "len" {
-												matchingvalue = len(mv)
-											}
-										case []interface{}:
-											if ks[i] == "len" {
-												matchingvalue = len(mv)
-											} else {
-												n, e := cast.ToIntE(ks[i])
-												if e != nil {
-													match = false
-													break
-												}
-												matchingvalue = mv[n]
-											}
-										case string:
-											if ks[i] == "len" {
-												matchingvalue = len(mv)
-											} else {
-												n, e := cast.ToIntE(ks[i])
-												if e != nil {
-													match = false
-													break
-												}
-												matchingvalue = mv[n]
-											}
-										default:
-											if ks[i] == "len" {
-												matchingvalue = 0
-											} else {
-												matchingvalue = nil
-											}
-										}
-									}
-								}
-								m, sv = matchvalue(ms[i], matchingvalue)
-								if !m {
-									match = false
-									break
-								}
-							}
-						}
-						matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv)
-					}
-					if match {
-						x++
-						matchingvalues = matchingvalues[:len(matchingvalues)-1]
-					} else {
-						matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv)
-					}
-				}
+				x, matchingvalues := MatchValues(rtn, ks, ms)
 				if n != x {
 					if len(rtn.Data) == 0 {
 						err = merrs.New("%s", fmt.Sprint("没有找到记录与期望值(", n, ")不符"))

+ 1 - 82
odbctest/odbcmql/mqls_doaction.go

@@ -57,88 +57,7 @@ func DoActionMatch(t *testing.T, args []any, mql string, rtn *odb.Result, toptio
 		breakup = true
 		return
 	}
-	x := 0
-	var matchingvalues [][]any
-	var matchingvalue any
-	for _, dat := range rtn.Data {
-		matchingvalues = append(matchingvalues, []any{})
-		m := false
-		sv := ""
-		match := true
-		for i, k := range ks {
-			matchingvalue = dat[k]
-			m, sv = matchvalue(ms[i], matchingvalue)
-			if !m {
-				ks := strings.Split(k, ".")
-				if len(ks) <= 1 {
-					match = false
-					break
-				} else {
-					k := ""
-					for i := 0; match && i < len(ks); i++ {
-						if matchingvalue == nil {
-							if k != "" {
-								k += "."
-							}
-							k += ks[i]
-							matchingvalue = dat[k]
-							if matchingvalue == nil && ks[i] == "len" {
-								matchingvalue = 0
-							}
-						} else {
-							switch mv := matchingvalue.(type) {
-							case map[string]any:
-								matchingvalue = mv[ks[i]]
-								if matchingvalue == nil && ks[i] == "len" {
-									matchingvalue = len(mv)
-								}
-							case []any:
-								if ks[i] == "len" {
-									matchingvalue = len(mv)
-								} else {
-									n, e := cast.ToIntE(ks[i])
-									if e != nil {
-										match = false
-										break
-									}
-									matchingvalue = mv[n]
-								}
-							case string:
-								if ks[i] == "len" {
-									matchingvalue = len(mv)
-								} else {
-									n, e := cast.ToIntE(ks[i])
-									if e != nil {
-										match = false
-										break
-									}
-									matchingvalue = mv[n]
-								}
-							default:
-								if ks[i] == "len" {
-									matchingvalue = 0
-								} else {
-									matchingvalue = nil
-								}
-							}
-						}
-					}
-					m, sv = matchvalue(ms[i], matchingvalue)
-					if !m {
-						match = false
-						break
-					}
-				}
-			}
-			matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv)
-		}
-		if match {
-			x++
-			matchingvalues = matchingvalues[:len(matchingvalues)-1]
-		} else {
-			matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv)
-		}
-	}
+	x, matchingvalues := MatchValues(rtn, ks, ms)
 	if x == 0 {
 		if len(rtn.Data) == 0 {
 			err = merrs.New("%s", "没有找到记录与期望值不符")

+ 144 - 0
odbctest/odbcmql/mqls_match.go

@@ -0,0 +1,144 @@
+package odbcmql
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	odb "git.wecise.com/wecise/odb-go/odb"
+	"gitee.com/wecisecode/util/cast"
+)
+
+func MatchValues(rtn *odb.Result, ks []string, ms []any) (x int, matchingvalues [][]any) {
+	var matchingvalue any
+	for _, dat := range rtn.Data {
+		matchingvalues = append(matchingvalues, []any{})
+		m := false
+		sv := ""
+		match := true
+		for i, k := range ks {
+			matchingvalue = dat[k]
+			m, sv = matchvalue(ms[i], matchingvalue)
+			if !m {
+				ks := strings.Split(k, ".")
+				if len(ks) <= 1 {
+					match = false
+					break
+				} else {
+					k := ""
+					for i := 0; match && i < len(ks); i++ {
+						if matchingvalue == nil {
+							if k != "" {
+								k += "."
+							}
+							k += ks[i]
+							matchingvalue = dat[k]
+							if matchingvalue == nil && ks[i] == "len" {
+								matchingvalue = 0
+							}
+						} else {
+							switch mv := matchingvalue.(type) {
+							case map[string]any:
+								matchingvalue = mv[ks[i]]
+								if matchingvalue == nil && ks[i] == "len" {
+									matchingvalue = len(mv)
+								}
+							case []any:
+								if ks[i] == "len" {
+									matchingvalue = len(mv)
+								} else {
+									n, e := cast.ToIntE(ks[i])
+									if e != nil {
+										match = false
+										break
+									}
+									matchingvalue = mv[n]
+								}
+							case string:
+								if ks[i] == "len" {
+									matchingvalue = len(mv)
+								} else {
+									n, e := cast.ToIntE(ks[i])
+									if e != nil {
+										match = false
+										break
+									}
+									matchingvalue = mv[n]
+								}
+							default:
+								if ks[i] == "len" {
+									matchingvalue = 0
+								} else {
+									matchingvalue = nil
+								}
+							}
+						}
+					}
+					m, sv = matchvalue(ms[i], matchingvalue)
+					if !m {
+						match = false
+						break
+					}
+				}
+			}
+			matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv)
+		}
+		if match {
+			x++
+			matchingvalues = matchingvalues[:len(matchingvalues)-1]
+		} else {
+			matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv)
+		}
+	}
+	return
+}
+
+func matchvalue(matcher any, matchingvalue any) (bool, string) {
+	switch m := matcher.(type) {
+	case *regexp.Regexp:
+		switch v := matchingvalue.(type) {
+		case string:
+			return m.MatchString(v), v
+		default:
+			sv := fmt.Sprintf("%#v", matchingvalue)
+			return m.MatchString(sv), sv
+		}
+	case string:
+		sv := ""
+		switch matchingvalue.(type) {
+		case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, bool:
+			sv = fmt.Sprintf("%v", matchingvalue)
+		case float32, float64:
+			sv = fmt.Sprintf("%v", matchingvalue)
+			fvrange := strings.Split(m, "~")
+			if len(fvrange) > 1 {
+				return sv >= fvrange[0] && sv <= fvrange[len(fvrange)-1], sv
+			}
+		default:
+			sv = fmt.Sprintf("%#v", matchingvalue)
+		}
+		return sv == m, sv
+	case *Action:
+		switch m.Name {
+		case "<FUZZY>":
+			return matchFuzzy(matchingvalue, m.Args)
+		}
+	}
+	panic("未定义的匹配类型")
+}
+
+func matchFuzzy(matchingvalue any, mvrange []any) (bool, string) {
+	sv := ""
+	switch matchingvalue.(type) {
+	case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, bool, float32, float64, string:
+		sv = fmt.Sprintf("%v", matchingvalue)
+	default:
+		sv = fmt.Sprintf("%#v", matchingvalue)
+	}
+	if len(mvrange) == 0 {
+		return false, sv
+	}
+	m1 := fmt.Sprintf("%v", mvrange[0])
+	m2 := fmt.Sprintf("%v", mvrange[len(mvrange)-1])
+	return sv >= m1 && sv <= m2, sv
+}