示例#1
0
func TestSqlDelete(t *testing.T) {

	db := datasource.NewContextSimple()
	user1 := map[string]value.Value{
		"user_id":    value.NewIntValue(5),
		"item_count": value.NewStringValue("5"),
		"bval":       value.NewBoolValue(true),
		"bvalf":      value.NewBoolValue(false),
		"reg_date":   value.NewStringValue("2014/11/01"),
		"name":       value.NewStringValue("bob")}
	db.Insert(user1)
	user2 := map[string]value.Value{
		"user_id":    value.NewIntValue(6),
		"item_count": value.NewStringValue("5"),
		"reg_date":   value.NewStringValue("2012/11/01"),
		"name":       value.NewStringValue("allison")}
	db.Insert(user2)
	assert.Tf(t, len(db.Rows) == 2, "has 2 users")
	verifySqlDelete(t, `
		DELETE FROM mytable
		WHERE yy(reg_date) == 14
		`, db)

	assert.Tf(t, len(db.Rows) == 1, "must have 1 rows: %v  %v", len(db.Rows), db.Rows)
	assert.Tf(t, db.Rows[0]["name"].ToString() == "allison", "%v", db.Rows)
}
示例#2
0
func TestBuiltins(t *testing.T) {
	for _, biTest := range builtinTests {

		writeContext := datasource.NewContextSimple()

		//u.Debugf("expr:  %v", biTest.expr)
		exprVm, err := vm.NewVm(biTest.expr)
		assert.Tf(t, err == nil, "parse err: %v on %s", err, biTest.expr)

		err = exprVm.Execute(writeContext, readContext)
		if biTest.val.Err() {

			assert.Tf(t, err != nil, "%v  expected err: %v", biTest.expr, err)

		} else {
			tval := biTest.val
			assert.Tf(t, err == nil, "not nil err: %s  %v", biTest.expr, err)

			val, ok := writeContext.Get("")
			assert.Tf(t, ok, "Not ok Get? %#v", writeContext)

			//u.Debugf("Type:  %T  %T", val, tval.Value)

			switch testVal := biTest.val.(type) {
			case value.StringsValue:
				//u.Infof("Sweet, is StringsValue:")
				sa := tval.(value.StringsValue).Value().([]string)
				sb := val.Value().([]string)
				sort.Strings(sa)
				sort.Strings(sb)
				assert.Tf(t, strings.Join(sa, ",") == strings.Join(sb, ","),
					"should be == expect %v but was %v  %v", tval.Value(), val.Value(), biTest.expr)
			case value.MapValue:
				if len(testVal.Val()) == 0 {
					// we didn't expect it to work?
					_, ok := val.(value.MapValue)
					assert.Tf(t, !ok, "Was able to convert to mapvalue but should have failed %#v", val)
				} else {
					mv, ok := val.(value.MapValue)
					assert.Tf(t, ok, "Was able to convert to mapvalue: %#v", val)
					//u.Debugf("mv: %T  %v", mv, val)
					assert.Tf(t, len(testVal.Val()) == len(mv.Val()), "Should have same size maps")
					mivals := mv.Val()
					for k, v := range testVal.Val() {
						valVal := mivals[k]
						//u.Infof("k:%v  v:%v   valval:%v", k, v.Value(), valVal.Value())
						assert.Equalf(t, valVal.Value(), v.Value(), "Must have found k/v:  %v \n\t%#v \n\t%#v", k, v, valVal)
					}
				}

			default:
				assert.Tf(t, val.Value() == tval.Value(),
					"should be == expect %v but was %v  %v", tval.Value(), val.Value(), biTest.expr)
			}
		}

	}
}
示例#3
0
func TestRunExpr(t *testing.T) {

	for _, test := range vmTests {

		if *NameMatch != "" && !strings.Contains(test.name, *NameMatch) {
			continue
		}

		//u.Debugf("about to parse: %v", test.qlText)
		exprVm, err := NewVm(test.qlText)

		//u.Infof("After Parse: %v  err=%v", test.qlText, err)
		switch {
		case err == nil && !test.parseok:
			t.Errorf("%q: 1 expected error; got none", test.name)
			continue
		case err != nil && test.parseok:
			t.Errorf("%q: 2 unexpected error: %v", test.name, err)
			continue
		case err != nil && !test.parseok:
			// expected error, got one
			if testing.Verbose() {
				u.Infof("%s: %s\n\t%s", test.name, test.qlText, err)
			}
			continue
		}

		writeContext := datasource.NewContextSimple()
		err = exprVm.Execute(writeContext, test.context)
		if exprVm.Tree != nil && exprVm.Tree.Root != nil {
			//Eval(writeContext, exprVm.Tree.Root)
		}

		results, _ := writeContext.Get("")
		//u.Infof("results:  %T %v  err=%v", results, results, err)
		if err != nil && test.evalok {
			t.Errorf("\n%s -- %v: \n\t%v\nexpected\n\t'%v'", test.name, test.qlText, results, test.result)
		}
		if test.result == nil && results != nil {
			t.Errorf("%s - should have nil result, but got: %v", test.name, results)
			continue
		}
		if test.result != nil && results == nil {
			t.Errorf("%s - should have non-nil result but was nil", test.name)
			continue
		}

		//u.Infof("results=%T   %#v", results, results)
		if test.result != nil && results.Value() != test.result {
			t.Fatalf("\n%s -- %v: \n\t%v--%T\nexpected\n\t%v--%T", test.name, test.qlText, results.Value(), results.Value(), test.result, test.result)
		} else if test.result == nil {
			// we expected nil
		}
	}
}
示例#4
0
func verifySqlWrite(t *testing.T, sql string) *datasource.ContextSimple {

	sqlVm, err := NewSqlVm(sql)
	assert.Tf(t, err == nil, "Should not err %v", err)
	assert.Tf(t, sqlVm != nil, "Should create vm & parse sql %v", sqlVm)

	writeContext := datasource.NewContextSimple()

	err = sqlVm.ExecuteInsert(writeContext)
	assert.Tf(t, err == nil, "non nil err: %v", err)

	return writeContext
}
示例#5
0
文件: main.go 项目: kyledj/qlbridge
func runParse(repeat int, sql string, readContext expr.ContextReader) {
	for i := 0; i < repeat; i++ {
		sqlVm, err := expr.ParseSqlVm(sql)
		if err != nil {
			panic(err.Error())
		}
		sel := sqlVm.(*expr.SqlSelect)
		writeContext := datasource.NewContextSimple()
		_, err = vm.EvalSql(sel, writeContext, readContext)
		if err != nil {
			panic(err.Error())
		}
	}
}
示例#6
0
func verifyBenchmarkSql(t *testing.B, sql string, readContext datasource.ContextReader) *datasource.ContextSimple {

	sqlVm, err := NewSqlVm(sql)
	if err != nil {
		t.Fail()
	}

	writeContext := datasource.NewContextSimple()
	err = sqlVm.Execute(writeContext, readContext)
	if err != nil {
		t.Fail()
	}

	return writeContext
}
示例#7
0
func verifySql(t *testing.T, sql string, readrows []datasource.ContextReader) *datasource.ContextSimple {

	sqlVm, err := NewSqlVm(sql)
	assert.Tf(t, err == nil, "Should not err %v", err)
	assert.Tf(t, sqlVm != nil, "Should create vm & parse sql %v", sqlVm)

	writeContext := datasource.NewContextSimple()
	for _, row := range readrows {

		err = sqlVm.Execute(writeContext, row)
		assert.Tf(t, err == nil, "non nil err: %v", err)
	}

	return writeContext
}
示例#8
0
func BenchmarkVmExecuteNoParse(b *testing.B) {
	readContext := datasource.NewContextSimpleData(
		map[string]value.Value{
			"int5":       value.NewIntValue(5),
			"item_count": value.NewStringValue("5"),
			"reg_date":   value.NewStringValue("2014/11/01"),
			"user_id":    value.NewStringValue("abc")},
	)
	sqlVm, err := NewSqlVm(bmSql[0])
	if err != nil {
		b.Fail()
	}
	writeContext := datasource.NewContextSimple()
	b.ReportAllocs()
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		err = sqlVm.Execute(writeContext, readContext)
		if err != nil {
			b.Fail()
		}
	}
}
示例#9
0
func TestFilterQlVm(t *testing.T) {
	t.Parallel()

	t1, _ := dateparse.ParseAny("12/18/2015")
	//u.Infof("t1 %v", t1)
	nminus1 := time.Now().Add(time.Hour * -1)
	tr := true
	user := &User{
		Name:          "Yoda",
		Created:       t1,
		Updated:       &nminus1,
		Authenticated: true,
		HasSession:    &tr,
		Address:       Address{"Detroit", 55},
		Roles:         []string{"admin", "api"},
		BankAmount:    55.5,
	}

	readers := []expr.ContextReader{
		datasource.NewContextWrapper(user),
		datasource.NewContextSimpleNative(map[string]interface{}{
			"city": "Peoria, IL",
			"zip":  5,
		}),
	}

	nc := datasource.NewNestedContextReader(readers, time.Now())

	hits := []string{
		`FILTER name == "Yoda"`,                         // upper case sensitive name
		`FILTER name != "yoda"`,                         // we should be case-sensitive by default
		`FILTER name = "Yoda"`,                          // is equivalent to ==
		`FILTER "Yoda" == name`,                         // reverse order of identity/value
		`FILTER name != "Anakin"`,                       // negation on missing fields == true
		`FILTER first_name != "Anakin"`,                 // key doesn't exist
		`FILTER tolower(name) == "yoda"`,                // use functions in evaluation
		`FILTER FullName == "Yoda, Jedi"`,               // use functions on structs in evaluation
		`FILTER Address.City == "Detroit"`,              // traverse struct with path.field
		`FILTER name LIKE "*da"`,                        // LIKE
		`FILTER name NOT LIKE "*kin"`,                   // LIKE Negation
		`FILTER name CONTAINS "od"`,                     // Contains
		`FILTER name NOT CONTAINS "kin"`,                // Contains
		`FILTER roles INTERSECTS ("user", "api")`,       // Intersects
		`FILTER roles NOT INTERSECTS ("user", "guest")`, // Intersects
		`FILTER Created < "now-1d"`,                     // Date Math
		`FILTER Updated > "now-2h"`,                     // Date Math
		`FILTER *`,                                      // match all
		`FILTER OR (
			EXISTS name,       -- inline comments
			EXISTS not_a_key,  -- more inline comments
		)`,
		// show that line-breaks serve as expression separators
		`FILTER OR (
			EXISTS name
			EXISTS not_a_key   -- even if they have inline comments
		)`,
		//`FILTER a == "Yoda" AND b == "Peoria, IL" AND c == 5`,
		`FILTER AND (name == "Yoda", city == "Peoria, IL", zip == 5, BankAmount > 50)`,
		`FILTER AND (zip == 5, "Yoda" == name, OR ( city IN ( "Portland, OR", "New York, NY", "Peoria, IL" ) ) )`,
		`FILTER OR (
			EXISTS q, 
			AND ( 
				zip > 0, 
				OR ( zip > 10000, zip < 100 ) 
			), 
			NOT ( name == "Yoda" ) )`,
	}

	for _, q := range hits {
		fs, err := rel.ParseFilterQL(q)
		assert.Equal(t, nil, err)
		match, err := NewFilterVm(nil).Matches(nc, fs)
		assert.Equalf(t, nil, err, "error matching on query %q: %v", q, err)
		assert.T(t, match, q)
	}

	misses := []string{
		`FILTER name == "yoda"`, // casing
		"FILTER OR (false, false, AND (true, false))",
		`FILTER AND (name == "Yoda", city == "xxx", zip == 5)`,
	}

	for _, q := range misses {
		fs, err := rel.ParseFilterQL(q)
		assert.Equal(t, nil, err)
		match, err := NewFilterVm(nil).Matches(nc, fs)
		assert.Equal(t, nil, err)
		assert.T(t, !match)
	}

	// Filter Select Statements
	filterSelects := []fsel{
		fsel{`select name, zip FROM mycontext FILTER name == "Yoda"`, map[string]interface{}{"name": "Yoda", "zip": 5}},
	}
	for _, test := range filterSelects {

		//u.Debugf("about to parse: %v", test.qlText)
		sel, err := rel.ParseFilterSelect(test.query)
		assert.T(t, err == nil, "expected no error but got ", err, " for ", test.query)

		writeContext := datasource.NewContextSimple()
		_, err = EvalFilerSelect(sel, nil, writeContext, nc)
		assert.T(t, err == nil, "expected no error but got ", err, " for ", test.query)

		for key, val := range test.expect {
			v := value.NewValue(val)
			v2, ok := writeContext.Get(key)
			assert.Tf(t, ok, "Get(%q)=%v but got: %#v", key, val, writeContext.Row())
			assert.Equalf(t, v2.Value(), v.Value(), "?? %s  %v!=%v %T %T", key, v.Value(), v2.Value(), v.Value(), v2.Value())
		}
	}
}
示例#10
0
// Create handler function for evaluation (ie, field selection from tuples)
func (m *Projection) projectionEvaluator() MessageHandler {
	out := m.MessageOut()
	columns := m.sql.Columns
	// if len(m.sql.From) > 1 && m.sql.From[0].Source != nil && len(m.sql.From[0].Source.Columns) > 0 {
	// 	// we have re-written this query, lets build new list of columns
	// 	columns = make(expr.Columns, 0)
	// 	for _, from := range m.sql.From {
	// 		for _, col := range from.Source.Columns {
	// 			columns = append(columns, col)
	// 		}
	// 	}
	// }
	return func(ctx *expr.Context, msg datasource.Message) bool {
		// defer func() {
		// 	if r := recover(); r != nil {
		// 		u.Errorf("crap, %v", r)
		// 	}
		// }()

		//u.Infof("got projection message: %T %#v", msg, msg.Body())
		var outMsg datasource.Message
		switch mt := msg.(type) {
		case *datasource.SqlDriverMessageMap:
			// readContext := datasource.NewContextUrlValues(uv)
			// use our custom write context for example purposes
			writeContext := datasource.NewContextSimple()
			outMsg = writeContext
			//u.Debugf("about to project: %#v", mt)
			for _, col := range columns {
				if col.ParentIndex < 0 {
					continue
				}
				//u.Debugf("col: idx:%v pidx:%v key:%v   %s", col.Index, col.ParentIndex, col.Key(), col.Expr)
				if col.Guard != nil {
					ifColValue, ok := vm.Eval(mt, col.Guard)
					if !ok {
						u.Errorf("Could not evaluate if:   %v", col.Guard.String())
						//return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String())
					}
					//u.Debugf("if eval val:  %T:%v", ifColValue, ifColValue)
					switch ifColVal := ifColValue.(type) {
					case value.BoolValue:
						if ifColVal.Val() == false {
							//u.Debugf("Filtering out col")
							continue
						}
					}
				}
				if col.Star {
					for k, v := range mt.Row() {
						writeContext.Put(&expr.Column{As: k}, nil, value.NewValue(v))
					}
				} else {
					v, ok := vm.Eval(mt, col.Expr)
					if !ok {
						u.Warnf("failed eval key=%v  val=%#v expr:%s   mt:%#v", col.Key(), v, col.Expr, mt)
					} else if v == nil {
						u.Debugf("evaled: key=%v  val=%v", col.Key(), v)
						writeContext.Put(col, mt, v)
					} else {
						//u.Debugf("evaled: key=%v  val=%v", col.Key(), v.Value())
						writeContext.Put(col, mt, v)
					}
				}
			}

		case *datasource.ContextUrlValues:
			// readContext := datasource.NewContextUrlValues(uv)
			// use our custom write context for example purposes
			writeContext := datasource.NewContextSimple()
			outMsg = writeContext
			//u.Infof("about to project: colsct%v %#v", len(sql.Columns), outMsg)
			for _, col := range columns {
				//u.Debugf("col:   %#v", col)
				if col.Guard != nil {
					ifColValue, ok := vm.Eval(mt, col.Guard)
					if !ok {
						u.Errorf("Could not evaluate if:   %v", col.Guard.String())
						//return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String())
					}
					//u.Debugf("if eval val:  %T:%v", ifColValue, ifColValue)
					switch ifColVal := ifColValue.(type) {
					case value.BoolValue:
						if ifColVal.Val() == false {
							//u.Debugf("Filtering out col")
							continue
						}
					}
				}
				if col.Star {
					for k, v := range mt.Row() {
						writeContext.Put(&expr.Column{As: k}, nil, v)
					}
				} else {
					//u.Debugf("tree.Root: as?%v %#v", col.As, col.Expr)
					v, ok := vm.Eval(mt, col.Expr)
					//u.Debugf("evaled: ok?%v key=%v  val=%v", ok, col.Key(), v)
					if ok {
						writeContext.Put(col, mt, v)
					}
				}

			}
		default:
			u.Errorf("could not project msg:  %T", msg)
		}

		//u.Debugf("completed projection for: %p %#v", out, outMsg)
		select {
		case out <- outMsg:
			return true
		case <-m.SigChan():
			return false
		}
	}
}
示例#11
0
// Create handler function for evaluation (ie, field selection from tuples)
func projectionEvaluator(sql *expr.SqlSelect, task TaskRunner) MessageHandler {
	out := task.MessageOut()
	//evaluator := vm.Evaluator(where)
	return func(ctx *Context, msg datasource.Message) bool {
		defer func() {
			if r := recover(); r != nil {
				u.Errorf("crap, %v", r)
			}
		}()

		//u.Infof("got projection message: %#v", msg.Body())
		var outMsg datasource.Message
		switch mt := msg.(type) {
		case *datasource.SqlDriverMessageMap:
			// readContext := datasource.NewContextUrlValues(uv)
			// use our custom write context for example purposes
			writeContext := datasource.NewContextSimple()
			outMsg = writeContext
			//u.Infof("about to project: colsct%v %#v", len(sql.Columns), outMsg)
			for _, from := range sql.From {
				for _, col := range from.Columns {
					//u.Debugf("col:   %#v", col)
					if col.Guard != nil {
						ifColValue, ok := vm.Eval(mt, col.Guard)
						if !ok {
							u.Errorf("Could not evaluate if:   %v", col.Guard.StringAST())
							//return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String())
						}
						//u.Debugf("if eval val:  %T:%v", ifColValue, ifColValue)
						switch ifColVal := ifColValue.(type) {
						case value.BoolValue:
							if ifColVal.Val() == false {
								//u.Debugf("Filtering out col")
								continue
							}
						}
					}
					if col.Star {
						for k, v := range mt.Vals {
							writeContext.Put(&expr.Column{As: k}, nil, value.NewValue(v))
						}
					} else {
						//u.Debugf("tree.Root: as?%v %v", col.As, col.Expr.String())
						v, ok := vm.Eval(mt, col.Expr)
						//u.Debugf("evaled: ok?%v key=%v  val=%v", ok, col.Key(), v)
						if ok {
							writeContext.Put(col, mt, v)
						}
					}
				}
			}

		case *datasource.ContextUrlValues:
			// readContext := datasource.NewContextUrlValues(uv)
			// use our custom write context for example purposes
			writeContext := datasource.NewContextSimple()
			outMsg = writeContext
			//u.Infof("about to project: colsct%v %#v", len(sql.Columns), outMsg)
			for _, col := range sql.Columns {
				//u.Debugf("col:   %#v", col)
				if col.Guard != nil {
					ifColValue, ok := vm.Eval(mt, col.Guard)
					if !ok {
						u.Errorf("Could not evaluate if:   %v", col.Guard.StringAST())
						//return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String())
					}
					//u.Debugf("if eval val:  %T:%v", ifColValue, ifColValue)
					switch ifColVal := ifColValue.(type) {
					case value.BoolValue:
						if ifColVal.Val() == false {
							//u.Debugf("Filtering out col")
							continue
						}
					}
				}
				if col.Star {
					for k, v := range mt.Row() {
						writeContext.Put(&expr.Column{As: k}, nil, v)
					}
				} else {
					//u.Debugf("tree.Root: as?%v %#v", col.As, col.Expr)
					v, ok := vm.Eval(mt, col.Expr)
					//u.Debugf("evaled: ok?%v key=%v  val=%v", ok, col.Key(), v)
					if ok {
						writeContext.Put(col, mt, v)
					}
				}

			}
		default:
			u.Errorf("could not project msg:  %T", msg)
		}

		//u.Debugf("completed projection for: %p %#v", out, outMsg)
		select {
		case out <- outMsg:
			return true
		case <-task.SigChan():
			return false
		}
	}
}