Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tree: move tests that pull in server to a different package #49737

Merged
merged 1 commit into from
Jun 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 0 additions & 194 deletions pkg/sql/sem/tree/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,23 @@ package tree_test

import (
"context"
gosql "database/sql"
"fmt"
"path/filepath"
"regexp"
"strings"
"testing"

"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/col/coldata"
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
"github.com/cockroachdb/cockroach/pkg/sql/colexec"
"github.com/cockroachdb/cockroach/pkg/sql/colexecbase"
"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
"github.com/cockroachdb/cockroach/pkg/sql/execinfrapb"
"github.com/cockroachdb/cockroach/pkg/sql/opt/exec/execbuilder"
"github.com/cockroachdb/cockroach/pkg/sql/opt/optbuilder"
"github.com/cockroachdb/cockroach/pkg/sql/opt/xform"
"github.com/cockroachdb/cockroach/pkg/sql/parser"
"github.com/cockroachdb/cockroach/pkg/sql/rowexec"
_ "github.com/cockroachdb/cockroach/pkg/sql/sem/builtins"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
"github.com/cockroachdb/cockroach/pkg/sql/types"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
"github.com/cockroachdb/datadriven"
"github.com/stretchr/testify/require"
)

func TestEval(t *testing.T) {
Expand Down Expand Up @@ -94,189 +83,6 @@ func TestEval(t *testing.T) {
return evalCtx.NormalizeExpr(typedExpr)
})
})

// The opt and no-opt tests don't do an end-to-end SQL test. Do that
// here by executing a SELECT. In order to make the output be the same
// we have to also figure out what the expected output type is so we
// can correctly format the datum.
t.Run("sql", func(t *testing.T) {
s, sqlDB, _ := serverutils.StartServer(t, base.TestServerArgs{})
defer s.Stopper().Stop(ctx)

walk(t, func(t *testing.T, d *datadriven.TestData) string {
var res gosql.NullString
if err := sqlDB.QueryRow(fmt.Sprintf("SELECT (%s)::STRING", d.Input)).Scan(&res); err != nil {
return strings.TrimPrefix(err.Error(), "pq: ")
}
if !res.Valid {
return "NULL"
}

// We have a non-null result. We can't just return
// res.String here because these strings don't
// match the datum.String() representations. For
// example, a bitarray has a res.String of something
// like `1001001` but the datum representation is
// `B'1001001'`. Thus we have to parse res.String (a
// SQL result) back into a datum and return that.

expr, err := parser.ParseExpr(d.Input)
if err != nil {
t.Fatal(err)
}
// expr.TypeCheck to avoid constant folding.
semaCtx := tree.MakeSemaContext()
typedExpr, err := expr.TypeCheck(ctx, &semaCtx, types.Any)
if err != nil {
// An error here should have been found above by QueryRow.
t.Fatal(err)
}

switch typedExpr.ResolvedType().Family() {
case types.TupleFamily:
// ParseAndRequireString doesn't handle tuples, so we have to convert them ourselves.
var datums tree.Datums
// Fetch the original expression's tuple values.
tuple := typedExpr.(*tree.Tuple)
for i, s := range strings.Split(res.String[1:len(res.String)-1], ",") {
if s == "" {
continue
}
// Figure out the type of the tuple value.
expr, err := tuple.Exprs[i].TypeCheck(ctx, &semaCtx, types.Any)
if err != nil {
t.Fatal(err)
}
// Now parse the new string as the expected type.
datum, err := tree.ParseAndRequireString(expr.ResolvedType(), s, evalCtx)
if err != nil {
t.Errorf("%s: %s", err, s)
return err.Error()
}
datums = append(datums, datum)
}
return tree.NewDTuple(typedExpr.ResolvedType(), datums...).String()
}
datum, err := tree.ParseAndRequireString(typedExpr.ResolvedType(), res.String, evalCtx)
if err != nil {
t.Errorf("%s: %s", err, res.String)
return err.Error()
}
return datum.String()
})
})

t.Run("vectorized", func(t *testing.T) {
walk(t, func(t *testing.T, d *datadriven.TestData) string {
if d.Input == "B'11111111111111111111111110000101'::int4" {
// Skip this test: https://github.com/cockroachdb/cockroach/pull/40790#issuecomment-532597294.
return strings.TrimSpace(d.Expected)
}
flowCtx := &execinfra.FlowCtx{
EvalCtx: evalCtx,
}
memMonitor := execinfra.NewTestMemMonitor(ctx, cluster.MakeTestingClusterSettings())
defer memMonitor.Stop(ctx)
acc := memMonitor.MakeBoundAccount()
defer acc.Close(ctx)
expr, err := parser.ParseExpr(d.Input)
require.NoError(t, err)
if _, ok := expr.(*tree.RangeCond); ok {
// RangeCond gets normalized to comparison expressions and its Eval
// method returns an error, so skip it for execution.
return strings.TrimSpace(d.Expected)
}
semaCtx := tree.MakeSemaContext()
typedExpr, err := expr.TypeCheck(ctx, &semaCtx, types.Any)
if err != nil {
// Skip this test as it's testing an expected error which would be
// caught before execution.
return strings.TrimSpace(d.Expected)
}
typs := []*types.T{typedExpr.ResolvedType()}

// inputTyps has no relation to the actual expression result type. Used
// for generating a batch.
inputTyps := []*types.T{types.Int}

batchesReturned := 0
args := colexec.NewColOperatorArgs{
Spec: &execinfrapb.ProcessorSpec{
Input: []execinfrapb.InputSyncSpec{{
Type: execinfrapb.InputSyncSpec_UNORDERED,
ColumnTypes: inputTyps,
}},
Core: execinfrapb.ProcessorCoreUnion{
Noop: &execinfrapb.NoopCoreSpec{},
},
Post: execinfrapb.PostProcessSpec{
RenderExprs: []execinfrapb.Expression{{Expr: d.Input}},
},
},
Inputs: []colexecbase.Operator{
&colexecbase.CallbackOperator{
NextCb: func(_ context.Context) coldata.Batch {
if batchesReturned > 0 {
return coldata.ZeroBatch
}
// It doesn't matter what types we create the input batch with.
batch := coldata.NewMemBatch(inputTyps, coldata.StandardColumnFactory)
batch.SetLength(1)
batchesReturned++
return batch
},
},
},
StreamingMemAccount: &acc,
// Unsupported post processing specs are wrapped and run through the
// row execution engine.
ProcessorConstructor: rowexec.NewProcessor,
}
args.TestingKnobs.UseStreamingMemAccountForBuffering = true
result, err := colexec.NewColOperator(ctx, flowCtx, args)
if testutils.IsError(err, "unsupported type") {
// Skip this test as execution is not supported by the vectorized
// engine.
return strings.TrimSpace(d.Expected)
} else {
require.NoError(t, err)
}

mat, err := colexec.NewMaterializer(
flowCtx,
0, /* processorID */
result.Op,
typs,
nil, /* output */
nil, /* metadataSourcesQueue */
nil, /* toClose */
nil, /* outputStatsToTrace */
nil, /* cancelFlow */
)
require.NoError(t, err)

var (
row sqlbase.EncDatumRow
meta *execinfrapb.ProducerMetadata
)
ctx = mat.Start(ctx)
row, meta = mat.Next()
if meta != nil {
if meta.Err != nil {
return fmt.Sprint(meta.Err)
}
t.Fatalf("unexpected metadata: %+v", meta)
}
if row == nil {
// Might be some metadata.
if meta := mat.DrainHelper(); meta.Err != nil {
t.Fatalf("unexpected error: %s", meta.Err)
}
t.Fatal("unexpected end of input")
}
return row[0].Datum.String()
})
})
}

func optBuildScalar(evalCtx *tree.EvalContext, e tree.Expr) (tree.TypedExpr, error) {
Expand Down
Loading