func TestEvaluator(t *testing.T) { defer leaktest.AfterTest(t)() v := [15]sqlbase.EncDatum{} for i := range v { v[i].SetDatum(sqlbase.ColumnType_INT, parser.NewDInt(parser.DInt(i))) } b := [2]sqlbase.EncDatum{} b[0].SetDatum(sqlbase.ColumnType_BOOL, parser.DBoolTrue) b[1].SetDatum(sqlbase.ColumnType_BOOL, parser.DBoolFalse) var nullInt sqlbase.EncDatum nullInt.SetDatum(sqlbase.ColumnType_INT, parser.DNull) testCases := []struct { spec EvaluatorSpec input sqlbase.EncDatumRows expected sqlbase.EncDatumRows }{ { spec: EvaluatorSpec{ Exprs: []Expression{{Expr: "@2"}, {Expr: "(((@1)))"}}, }, input: sqlbase.EncDatumRows{ {v[1], v[2]}, {v[3], v[4]}, {v[6], v[2]}, {v[7], v[2]}, {v[8], v[4]}, {nullInt, nullInt}, }, expected: sqlbase.EncDatumRows{ {v[2], v[1]}, {v[4], v[3]}, {v[2], v[6]}, {v[2], v[7]}, {v[4], v[8]}, {nullInt, nullInt}, }, }, { spec: EvaluatorSpec{ Exprs: []Expression{ {Expr: "@1 + @2"}, {Expr: "@1 - @2"}, {Expr: "@1 >= 8"}, }, }, input: sqlbase.EncDatumRows{ {v[10], v[0]}, {v[9], v[1]}, {v[8], v[2]}, {v[7], v[3]}, {v[6], v[4]}, }, expected: sqlbase.EncDatumRows{ {v[10], v[10], b[0]}, {v[10], v[8], b[0]}, {v[10], v[6], b[0]}, {v[10], v[4], b[1]}, {v[10], v[2], b[1]}, }, }, { spec: EvaluatorSpec{ Exprs: []Expression{ {Expr: "@1 AND @1"}, {Expr: "@1 AND @2"}, {Expr: "NOT @1"}, }, }, input: sqlbase.EncDatumRows{ {b[0], b[1]}, }, expected: sqlbase.EncDatumRows{ {b[0], b[1], b[1]}, }, }, { spec: EvaluatorSpec{ Exprs: []Expression{{Expr: "1"}}, }, input: sqlbase.EncDatumRows{ {v[1], v[2]}, {v[3], v[4]}, {v[6], v[2]}, {v[7], v[2]}, {v[8], v[4]}, }, expected: sqlbase.EncDatumRows{ {v[1]}, {v[1]}, {v[1]}, {v[1]}, {v[1]}, }, }, } for _, c := range testCases { es := c.spec in := &RowBuffer{rows: c.input} out := &RowBuffer{} flowCtx := FlowCtx{ Context: context.Background(), evalCtx: &parser.EvalContext{}, } ev, err := newEvaluator(&flowCtx, &es, in, out) if err != nil { t.Fatal(err) } ev.Run(nil) if out.err != nil { t.Fatal(out.err) } if !out.closed { t.Fatalf("output RowReceiver not closed") } if result := out.rows.String(); result != c.expected.String() { t.Errorf("invalid results: %s, expected %s'", result, c.expected.String()) } } }
func TestUnorderedSync(t *testing.T) { defer leaktest.AfterTest(t)() mrc := &MultiplexedRowChannel{} mrc.Init(5) for i := 1; i <= 5; i++ { go func(i int) { for j := 1; j <= 100; j++ { var a, b sqlbase.EncDatum a.SetDatum(sqlbase.ColumnType_INT, parser.NewDInt(parser.DInt(i))) b.SetDatum(sqlbase.ColumnType_INT, parser.NewDInt(parser.DInt(j))) row := sqlbase.EncDatumRow{a, b} mrc.PushRow(row) } mrc.Close(nil) }(i) } var retRows sqlbase.EncDatumRows for { row, err := mrc.NextRow() if err != nil { t.Fatal(err) } if row == nil { break } retRows = append(retRows, row) } // Verify all elements. for i := 1; i <= 5; i++ { j := 1 for _, row := range retRows { if int(*(row[0].Datum.(*parser.DInt))) == i { if int(*(row[1].Datum.(*parser.DInt))) != j { t.Errorf("Expected [%d %d], got %s", i, j, row) } j++ } } if j != 101 { t.Errorf("Missing [%d %d]", i, j) } } // Test case when one source closes with an error. mrc = &MultiplexedRowChannel{} mrc.Init(5) for i := 1; i <= 5; i++ { go func(i int) { for j := 1; j <= 100; j++ { var a, b sqlbase.EncDatum a.SetDatum(sqlbase.ColumnType_INT, parser.NewDInt(parser.DInt(i))) b.SetDatum(sqlbase.ColumnType_INT, parser.NewDInt(parser.DInt(j))) row := sqlbase.EncDatumRow{a, b} mrc.PushRow(row) } var err error if i == 3 { err = fmt.Errorf("Test error") } mrc.Close(err) }(i) } for { row, err := mrc.NextRow() if err != nil { if err.Error() != "Test error" { t.Error(err) } break } if row == nil { t.Error("Did not receive expected error") } } }