Skip to content

Commit

Permalink
Merge pull request #101905 from cockroachdb/blathers/backport-release…
Browse files Browse the repository at this point in the history
…-23.1-100655

release-23.1: opt: improve opt-tester ddl support (#101905)

Co-Authored-By: Tommy Reilly <[email protected]>
  • Loading branch information
rytaft and cucaroach authored May 15, 2023
2 parents ac3bdf3 + 3a6a8a8 commit ea3962e
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 11 deletions.
103 changes: 103 additions & 0 deletions pkg/sql/opt/testutils/opttester/testdata/ddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
exec-ddl
CREATE TYPE greeting AS ENUM ('hello', 'howdy', 'hi')
----

exec-ddl
CREATE TABLE t (x INT, g greeting)
----

exec-ddl
ALTER TABLE t INJECT STATISTICS '[
{
"avg_size": 4,
"columns": [
"g"
],
"created_at": "2023-03-14 14:05:25.635783",
"distinct_count": 3,
"histo_buckets": [
{
"distinct_range": 0,
"num_eq": 1,
"num_range": 0,
"upper_bound": "hello"
},
{
"distinct_range": 0,
"num_eq": 2,
"num_range": 0,
"upper_bound": "howdy"
},
{
"distinct_range": 0,
"num_eq": 3,
"num_range": 0,
"upper_bound": "hi"
}
],
"histo_col_type": "greeting",
"histo_version": 2,
"name": "__auto__",
"null_count": 0,
"row_count": 6
},
{
"avg_size": 4,
"columns": [
"x"
],
"created_at": "2023-03-14 14:05:25.635783",
"distinct_count": 10,
"histo_buckets": [
{
"distinct_range": 0,
"num_eq": 0,
"num_range": 0,
"upper_bound": "0"
},
{
"distinct_range": 5,
"num_eq": 1,
"num_range": 5,
"upper_bound": "10"
}
],
"histo_col_type": "INT8",
"histo_version": 2,
"name": "__auto__",
"null_count": 0,
"row_count": 6
}
]'
----

opt format=show-stats
SELECT * FROM t WHERE x > 0 AND g = 'howdy'
----
select
├── columns: x:1(int!null) g:2(greeting!null)
├── immutable
├── stats: [rows=2, distinct(1)=2, null(1)=0, distinct(2)=1, null(2)=0]
│ histogram(1)= 0 0 1.6667 0.33333
│ <--- 0 --------- 10 --
│ histogram(2)= 0 2
│ <--- 'howdy'
├── fd: ()-->(2)
├── scan t
│ ├── columns: x:1(int) g:2(greeting)
│ └── stats: [rows=6, distinct(1)=6, null(1)=0, distinct(2)=3, null(2)=0]
│ histogram(1)= 0 0 5 1
│ <--- 0 --- 10
│ histogram(2)= 0 1 0 2 0 3
│ <--- 'hello' --- 'howdy' --- 'hi'
└── filters
├── gt [type=bool, outer=(1), constraints=(/1: [/1 - ]; tight)]
│ ├── variable: x:1 [type=int]
│ └── const: 0 [type=int]
└── eq [type=bool, outer=(2), immutable, constraints=(/2: [/'howdy' - /'howdy']; tight), fd=()-->(2)]
├── variable: g:2 [type=greeting]
└── const: 'howdy' [type=greeting]

exec-ddl
CREATE MATERIALIZED VIEW v AS SELECT x FROM t
----
6 changes: 3 additions & 3 deletions pkg/sql/opt/testutils/testcat/alter_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (tc *Catalog) AlterTable(stmt *tree.AlterTable) {
for _, cmd := range stmt.Cmds {
switch t := cmd.(type) {
case *tree.AlterTableInjectStats:
injectTableStats(tab, t.Stats)
injectTableStats(tab, t.Stats, tc)

case *tree.AlterTableAddConstraint:
switch d := t.ConstraintDef.(type) {
Expand All @@ -55,7 +55,7 @@ func (tc *Catalog) AlterTable(stmt *tree.AlterTable) {
}

// injectTableStats sets the table statistics as specified by a JSON object.
func injectTableStats(tt *Table, statsExpr tree.Expr) {
func injectTableStats(tt *Table, statsExpr tree.Expr, tc *Catalog) {
ctx := context.Background()
semaCtx := tree.MakeSemaContext()
evalCtx := eval.MakeTestingEvalContext(cluster.MakeTestingClusterSettings())
Expand All @@ -78,7 +78,7 @@ func injectTableStats(tt *Table, statsExpr tree.Expr) {
}
tt.Stats = make([]*TableStat, len(stats))
for i := range stats {
tt.Stats[i] = &TableStat{js: stats[i], tt: tt, evalCtx: &evalCtx}
tt.Stats[i] = &TableStat{js: stats[i], tt: tt, evalCtx: &evalCtx, tc: tc}
}
// Call ColumnOrdinal on all possible columns to assert that
// the column names are valid.
Expand Down
22 changes: 15 additions & 7 deletions pkg/sql/opt/testutils/testcat/create_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ func (tc *Catalog) CreateIndex(stmt *tree.CreateIndex, version descpb.IndexDescr
tn := stmt.Table
// Update the table name to include catalog and schema if not provided.
tc.qualifyTableName(&tn)
tab := tc.Table(&tn)

for _, idx := range tab.Indexes {
in := stmt.Name.String()
if idx.IdxName == in {
panic(errors.Newf(`relation "%s" already exists`, in))
tab, err := tc.LookupTable(&tn)
var view *View
if err == nil {
for _, idx := range tab.Indexes {
in := stmt.Name.String()
if idx.IdxName == in {
panic(errors.Newf(`relation "%s" already exists`, in))
}
}
} else {
view = tc.View(&tn)
}

// Convert stmt to a tree.IndexTableDef so that Table.addIndex can be used
Expand All @@ -48,5 +52,9 @@ func (tc *Catalog) CreateIndex(stmt *tree.CreateIndex, version descpb.IndexDescr
idxType = uniqueIndex

}
tab.addIndexWithVersion(indexTableDef, idxType, version)
if tab != nil {
tab.addIndexWithVersion(indexTableDef, idxType, version)
} else if view != nil {
view.addIndex(indexTableDef)
}
}
5 changes: 5 additions & 0 deletions pkg/sql/opt/testutils/testcat/create_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ func (tc *Catalog) CreateView(stmt *tree.CreateView) *View {

return view
}

func (*View) addIndex(stmt *tree.IndexTableDef) {
// TODO(cucaroach): implement
panic("view indexes are not supported by the test catalog")
}
20 changes: 19 additions & 1 deletion pkg/sql/opt/testutils/testcat/test_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,20 @@ func (tc *Catalog) Table(name *tree.TableName) *Table {
"\"%q\" is not a table", tree.ErrString(name)))
}

// LookupTable returns the test table that was previously added with the given
// name but returns an error if the name does not exist instead of panicking.
func (tc *Catalog) LookupTable(name *tree.TableName) (*Table, error) {
ds, _, err := tc.ResolveDataSource(context.TODO(), cat.Flags{}, name)
if err != nil {
return nil, err
}
if tab, ok := ds.(*Table); ok {
return tab, nil
}
return nil, pgerror.Newf(pgcode.WrongObjectType,
"\"%q\" is not a table", tree.ErrString(name))
}

// Tables returns a list of all tables added to the test catalog.
func (tc *Catalog) Tables() []*Table {
tables := make([]*Table, 0, len(tc.testSchema.dataSources))
Expand Down Expand Up @@ -1183,6 +1197,7 @@ type TableStat struct {
evalCtx *eval.Context
histogram []cat.HistogramBucket
histogramType *types.T
tc *Catalog
}

var _ cat.TableStatistic = &TableStat{}
Expand Down Expand Up @@ -1243,7 +1258,10 @@ func (ts *TableStat) Histogram() []cat.HistogramBucket {
if err != nil {
panic(err)
}
colType := tree.MustBeStaticallyKnownType(colTypeRef)
colType, err := tree.ResolveType(context.Background(), colTypeRef, ts.tc)
if err != nil {
return nil
}

var offset int
if ts.js.NullCount > 0 {
Expand Down

0 comments on commit ea3962e

Please sign in to comment.