mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
This so other packages can import and use them in their own tests.
(cherry picked from commit eec278893a)
119 lines
3.5 KiB
Go
119 lines
3.5 KiB
Go
// Copyright 2021 Molecula Corp. All rights reserved.
|
|
package sql3_test
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"sort"
|
|
"testing"
|
|
|
|
pilosa "github.com/featurebasedb/featurebase/v3"
|
|
"github.com/featurebasedb/featurebase/v3/sql3/parser"
|
|
planner_types "github.com/featurebasedb/featurebase/v3/sql3/planner/types"
|
|
sql_test "github.com/featurebasedb/featurebase/v3/sql3/test"
|
|
"github.com/featurebasedb/featurebase/v3/test"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestSQL_Execute(t *testing.T) {
|
|
c := test.MustRunCluster(t, 1)
|
|
defer c.Close()
|
|
|
|
svr := c.GetNode(0).Server
|
|
|
|
for i, test := range defs.TableTests {
|
|
t.Run(test.Name(i), func(t *testing.T) {
|
|
|
|
// Create a table with all field types.
|
|
if test.HasTable() {
|
|
_, _, err := sql_test.MustQueryRows(t, svr, test.CreateTable())
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
if test.HasTable() && test.HasData() {
|
|
// Populate fields with data.
|
|
_, _, err := sql_test.MustQueryRows(t, svr, test.InsertInto(t))
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
for i, sqltest := range test.SQLTests {
|
|
t.Run(sqltest.Name(i), func(t *testing.T) {
|
|
for _, sql := range sqltest.SQLs {
|
|
t.Run(fmt.Sprintf("sql-%s", sql), func(t *testing.T) {
|
|
log.Printf("SQL: %s", sql)
|
|
rows, headers, err := sql_test.MustQueryRows(t, svr, sql)
|
|
|
|
// Check expected error instead of results.
|
|
if sqltest.ExpErr != "" {
|
|
if assert.Error(t, err) {
|
|
assert.Contains(t, err.Error(), sqltest.ExpErr)
|
|
}
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
|
|
// Check headers.
|
|
assert.ElementsMatch(t, sqltest.ExpHdrs, headers)
|
|
|
|
// make a map of column name to header index
|
|
m := make(map[string]int)
|
|
for i := range headers {
|
|
m[headers[i].ColumnName] = i
|
|
}
|
|
|
|
// Put the expRows in the same column order as the headers returned
|
|
// by the query.
|
|
exp := make([][]interface{}, len(sqltest.ExpRows))
|
|
for i := range sqltest.ExpRows {
|
|
exp[i] = make([]interface{}, len(headers))
|
|
for j := range sqltest.ExpHdrs {
|
|
targetIdx := m[sqltest.ExpHdrs[j].ColumnName]
|
|
assert.GreaterOrEqual(t, len(sqltest.ExpRows[i]), len(headers),
|
|
"expected row set has fewer columns than returned headers")
|
|
exp[i][targetIdx] = sqltest.ExpRows[i][j]
|
|
}
|
|
}
|
|
|
|
if sqltest.SortStringKeys {
|
|
sortStringKeys(rows)
|
|
}
|
|
|
|
switch sqltest.Compare {
|
|
case defs.CompareExactOrdered:
|
|
assert.Equal(t, len(sqltest.ExpRows), len(rows))
|
|
assert.EqualValues(t, exp, rows)
|
|
case defs.CompareExactUnordered:
|
|
assert.Equal(t, len(sqltest.ExpRows), len(rows))
|
|
assert.ElementsMatch(t, exp, rows)
|
|
case defs.CompareIncludedIn:
|
|
assert.Equal(t, sqltest.ExpRowCount, len(rows))
|
|
for _, row := range rows {
|
|
assert.Contains(t, exp, row)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// sortStringKeys goes through an entire set of rows, and for any []string it
|
|
// finds, it orders the elements. This is obviously only useful in tests, and
|
|
// only in cases where we expect the elements to match, but we don't care what
|
|
// order they're in. It's basically the equivalent of assert.ElementsMatch(),
|
|
// but the way we use that on rows doesn't recurse down into the field values
|
|
// within each row.
|
|
func sortStringKeys(in [][]interface{}) {
|
|
for i := range in {
|
|
for j := range in[i] {
|
|
switch v := in[i][j].(type) {
|
|
case []string:
|
|
sort.Strings(v)
|
|
}
|
|
}
|
|
}
|
|
}
|