Created
March 26, 2018 19:00
-
-
Save palash25/d868e6bc2833d52eb009aab2c5fbbf51 to your computer and use it in GitHub Desktop.
Contains output of coala analysis run on the cockroachdb repo using GoVet and Gofmt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Executing section all... | |
Executing section all.go... | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:24] GoVetBear: This result has no patch attached. | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 223] » » » » argTypeVariant·:=·append(argType,·tree.ArgTypes{{objSpecArg.Name,·typ}}...) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 232] » » argTypes[i]·=·append(argType,·tree.ArgTypes{{"privilege",·types.String}}...) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 440] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 462] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 473] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 498] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 530] » » » Types:········tree.ArgTypes{{"val",·types.Any}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 541] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 569] » » » Types:············tree.ArgTypes{{"sequence_oid",·types.Oid}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 594] » » » Types:········tree.ArgTypes{{"type_oid",·types.Oid},·{"typemod",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 615] » » » Types:······tree.ArgTypes{{"table_oid",·types.Oid},·{"column_number",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 625] » » » Types:······tree.ArgTypes{{"object_oid",·types.Oid}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 633] » » » Types:······tree.ArgTypes{{"object_oid",·types.Oid},·{"catalog_name",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 643] » » » Types:······tree.ArgTypes{{"int",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 653] » » » Types:······tree.ArgTypes{{"object_oid",·types.Oid},·{"catalog_name",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 663] » » » Types:······tree.ArgTypes{{"int",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 673] » » » Types:······tree.ArgTypes{{"int",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 686] » » » Types:······tree.ArgTypes{{"oid",·types.Oid}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/pg_builtins.go | |
[ 703] » » » Types:······tree.ArgTypes{{"seconds",·types.Float}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
[WARNING][00:17:28] GoVetBear: This result has no patch attached. | |
pkg/sql/scrub_constraint.go | |
[ 82] » » » Tables:·tree.TableExprs{normalizableTableName}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.TableExprs composite literal uses unkeyed fields | |
[WARNING][00:17:29] GoVetBear: This result has no patch attached. | |
pkg/sql/upsert.go | |
[ 735] » » » updateExprs·=·append(updateExprs,·&tree.UpdateExpr{Names:·tree.NameList{n},·Expr:·expr}) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.NameList composite literal uses unkeyed fields | |
[WARNING][00:17:30] GoVetBear: This result has no patch attached. | |
pkg/sql/create_table.go | |
[ 349] » » » » » FromCols:·tree.NameList{col.Name}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.NameList composite literal uses unkeyed fields | |
[WARNING][00:17:32] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:32] GoVetBear: This result has no patch attached. | |
pkg/ccl/backupccl/backup_test.go | |
[ 480] » » DescriptorIDs:·sqlbase.IDs{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.IDs composite literal uses unkeyed fields | |
pkg/ccl/backupccl/backup_test.go | |
[ 495] » » DescriptorIDs:·sqlbase.IDs{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.IDs composite literal uses unkeyed fields | |
**** GofmtBear [Section <empty> | Severity NORMAL] **** | |
! ! Formatting can be improved. | |
[----] /home/palash25/Dev/cockroach/pkg/sql/opt/exec/factory.go | |
[++++] /home/palash25/Dev/cockroach/pkg/sql/opt/exec/factory.go | |
[ 1] // Copyright 2018 The Cockroach Authors. | |
[ 2] // | |
[ 3] // Licensed under the Apache License, Version 2.0 (the "License"); | |
[ 4] // you may not use this file except in compliance with the License. | |
[ 5] // You may obtain a copy of the License at | |
[ 6] // | |
[ 7] // http://www.apache.org/licenses/LICENSE-2.0 | |
[ 8] // | |
[ 9] // Unless required by applicable law or agreed to in writing, software | |
[ 10] // distributed under the License is distributed on an "AS IS" BASIS, | |
[ 11] // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
[ 12] // implied. See the License for the specific language governing | |
[ 13] // permissions and limitations under the License. | |
[ 14] | |
[ 15] package exec | |
[ 16] | |
[ 17] import ( | |
[ 18] "github.com/cockroachdb/cockroach/pkg/sql/opt" | |
[ 19] "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" | |
[ 20] "github.com/cockroachdb/cockroach/pkg/sql/sem/types" | |
[ 21] "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" | |
[ 22] "github.com/cockroachdb/cockroach/pkg/util" | |
[ 23] ) | |
[ 24] | |
[ 25] // Node represents a node in the execution tree (currently maps to a | |
[ 26] // sql.planNode). | |
[ 27] type Node interface{} | |
[ 28] | |
[ 29] // Factory defines the interface for building an execution plan, which consists | |
[ 30] // of a tree of execution nodes (currently a sql.planNode tree). | |
[ 31] // | |
[ 32] // The tree is always built bottom-up. The Construct methods either construct | |
[ 33] // leaf nodes, or they take other nodes previously constructed by this same | |
[ 34] // factory as children. | |
[ 35] // | |
[ 36] // The TypedExprs passed to these functions refer to columns of the input node | |
[ 37] // via IndexedVars. | |
[ 38] type Factory interface { | |
[ 39] // ConstructValues returns a node that outputs the given rows as results. | |
[ 40] ConstructValues(rows [][]tree.TypedExpr, cols sqlbase.ResultColumns) (Node, error) | |
[ 41] | |
[ 42] // ConstructScan returns a node that represents a scan of the given table. | |
[ 43] // Only the given set of needed columns are part of the result. | |
[ 44] // TODO(radu): support index constraints | |
[ 45] ConstructScan(table opt.Table, index opt.Index, needed ColumnOrdinalSet) (Node, error) | |
[ 46] | |
[ 47] // ConstructFilter returns a node that applies a filter on the results of | |
[ 48] // the given input node. | |
[ 49] ConstructFilter(n Node, filter tree.TypedExpr) (Node, error) | |
[ 50] | |
[ 51] // ConstructSimpleProject returns a node that applies a "simple" projection on the | |
[ 52] // results of the given input node. A simple projection is one that does not | |
[ 53] // involve new expressions; it's just a reshuffling of columns. This is a | |
[ 54] // more efficient version of ConstructRender. | |
[ 55] // The colNames argument is optional; if it is nil, the names of the | |
[ 56] // corresponding input columns are kept. | |
[ 57] ConstructSimpleProject(n Node, cols []ColumnOrdinal, colNames []string) (Node, error) | |
[ 58] | |
[ 59] // ConstructRender returns a node that applies a projection on the results of | |
[ 60] // the given input node. The projection can contain new expressions. | |
[ 61] ConstructRender(n Node, exprs tree.TypedExprs, colNames []string) (Node, error) | |
[ 62] | |
[ 63] // ConstructJoin returns a node that runs a hash-join between the results | |
[ 64] // of two input nodes. The expression can refer to columns from both inputs | |
[ 65] // using IndexedVars (first the left columns, then the right columns). | |
[ 66] ConstructJoin(joinType sqlbase.JoinType, left, right Node, onCond tree.TypedExpr) (Node, error) | |
[ 67] | |
[ 68] // ConstructGroupBy returns a node that runs an aggregation. If group columns | |
[ 69] // are specified, a set of aggregations is performed for each group of values | |
[ 70] // on those columns (otherwise there is a single group). | |
[ 71] ConstructGroupBy(input Node, groupCols []ColumnOrdinal, aggregations []AggInfo) (Node, error) | |
[ 72] | |
[ 73] // ConstructSetOp returns a node that performs a UNION / INTERSECT / EXCEPT | |
[ 74] // operation (either the ALL or the DISTINCT version). The left and right | |
[ 75] // nodes must have the same number of columns. | |
[ 76] ConstructSetOp(typ tree.UnionType, all bool, left, right Node) (Node, error) | |
[ 77] | |
[ 78] // ConstructSort returns a node that performs a resorting of the rows produced | |
[ 79] // by the input node. | |
[ 80] ConstructSort(input Node, ordering sqlbase.ColumnOrdering) (Node, error) | |
[ 81] | |
[ 82] // ConstructLimit returns a node that implements LIMIT and/or OFFSET on the | |
[ 83] // results of the given node. If only an offset is desired, limit should be | |
[ 84] // math.MaxInt64. | |
[ 85] ConstructLimit(input Node, limit int64, offset int64) (Node, error) | |
[ 86] | |
[ 87] // RenameColumns modifies the column names of a node. | |
[ 88] RenameColumns(input Node, colNames []string) (Node, error) | |
[ 89] } | |
[ 90] | |
[ 91] // ColumnOrdinal is the 0-based ordinal index of a column produced by a Node. | |
[ 92] type ColumnOrdinal int32 | |
[ 93] | |
[ 94] // ColumnOrdinalSet contains a set of ColumnOrdinal values as ints. | |
[ 95] type ColumnOrdinalSet = util.FastIntSet | |
[ 96] | |
[ 97] // AggInfo represents an aggregation (see ConstructGroupBy). | |
[ 98] type AggInfo struct { | |
[ 99] FuncName string | |
[ 100] Builtin *tree.Builtin | |
[ 101] ResultType types.T | |
[ 102] ArgCols []ColumnOrdinal | |
[ 103] } | |
[INFO][00:17:32] Applied 'ShowPatchAction' on 'pkg/sql/opt/exec/factory.go' from 'GofmtBear'. | |
[WARNING][00:17:32] GoVetBear: This result has no patch attached. | |
pkg/sql/opt/exec/factory.go | |
[ 23] ) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! expected type, found '=' | |
[WARNING][00:17:33] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:33] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:33] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:33] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:33] GoVetBear: This result has no patch attached. | |
pkg/util/encoding/encoding.go | |
[1756] » » return·buf,·false,·fmt.Errorf("value·type·is·not·%s·or·%s:·%s",·True,·False,·typ) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg True for printf verb %s of wrong type: encoding.Type | |
pkg/util/encoding/encoding.go | |
[1927] » » return·b,·errors.Errorf("value·type·is·not·%s:·%s",·expected,·typ) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg expected for printf verb %s of wrong type: encoding.Type | |
pkg/util/encoding/encoding.go | |
[1995] » » return·0,·errors.Errorf("unknown·type·%s",·typ) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg typ for printf verb %s of wrong type: encoding.Type | |
pkg/util/encoding/encoding.go | |
[2027] » » panic(fmt.Errorf("unknown·type:·%s",·typ)) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg typ for printf verb %s of wrong type: encoding.Type | |
pkg/util/encoding/encoding.go | |
[2110] » » return·b,·"",·errors.Errorf("unknown·type·%s",·typ) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg typ for printf verb %s of wrong type: encoding.Type | |
[WARNING][00:17:33] GoVetBear: This result has no patch attached. | |
pkg/sql/expr_filter_test.go | |
[ 198] » » » » » » return·true,·&tree.UnresolvedName{NumParts:·1,·Parts:·tree.NameParts{colName}} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.NameParts composite literal uses unkeyed fields | |
[WARNING][00:17:35] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:35] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:35] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:35] GoVetBear: This result has no patch attached. | |
pkg/sql/executor.go | |
[1345] » » res.SetColumns(sqlbase.ResultColumns{{Name:·"TRANSACTION·STATUS",·Typ:·types.String}}) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ResultColumns composite literal uses unkeyed fields | |
pkg/sql/executor.go | |
[1347] » » if·err·:=·res.AddRow(session.Ctx(),·tree.Datums{tree.NewDString(state)});·err·!=·nil·{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/executor.go | |
[1352] » » res.SetColumns(sqlbase.ResultColumns{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ResultColumns composite literal uses unkeyed fields | |
pkg/sql/executor.go | |
[1358] » » » » return·res.AddRow(ctx,·tree.Datums{tree.NewDString(field),·tree.NewDString(msg)}) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
[WARNING][00:17:36] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:36] GoVetBear: This result has no patch attached. | |
pkg/sql/group.go | |
[ 515] » » return·sqlbase.ColumnOrdering{{ColIdx:·f.argRenderIdx,·Direction:·encoding.Ascending}} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/group.go | |
[ 517] » » return·sqlbase.ColumnOrdering{{ColIdx:·f.argRenderIdx,·Direction:·encoding.Descending}} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
pkg/sql/sqlbase/table_test.go | |
[ 283] » » » » Array:····tree.Datums{tree.NewDInt(1)}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/sqlbase/table_test.go | |
[ 290] » » » » Array:····tree.Datums{tree.NewDInt(1),·tree.NewDInt(2),·tree.NewDInt(3)}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/sqlbase/table_test.go | |
[ 297] » » » » Array:····tree.Datums{tree.NewDString("foo"),·tree.NewDString("bar"),·tree.NewDString("baz")}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/sqlbase/table_test.go | |
[ 304] » » » » Array:····tree.Datums{tree.MakeDBool(true),·tree.MakeDBool(false)}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/sqlbase/table_test.go | |
[ 311] » » » » Array:····tree.Datums{tree.DNull}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/sqlbase/table_test.go | |
[ 319] » » » » Array:····tree.Datums{tree.NewDInt(1),·tree.DNull,·tree.DNull}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/sqlbase/table_test.go | |
[ 327] » » » » Array:·tree.Datums{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/sqlbase/table_test.go | |
[ 338] » » » » Array:·tree.Datums{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
pkg/sql/jobs/registry_external_test.go | |
[ 54] » » DescriptorIDs:·sqlbase.IDs{42}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.IDs composite literal uses unkeyed fields | |
[WARNING][00:17:37] GoVetBear: This result has no patch attached. | |
pkg/sql/show_cluster_setting.go | |
[ 152] » » » if·_,·err·:=·v.rows.AddRow(ctx,·tree.Datums{d});·err·!=·nil·{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:38] GoVetBear: This result has no patch attached. | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 54] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 58] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 90] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 94] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 131] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 135] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 182] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 186] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 247] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 251] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 286] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 290] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 325] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 329] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 364] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 369] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 404] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 408] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 432] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 436] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 463] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 467] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 497] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 501] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 527] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 531] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 574] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 578] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 607] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 611] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 637] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 641] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 752] » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 756] » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 845] » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/mergejoiner_test.go | |
[ 849] » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
[WARNING][00:17:39] GoVetBear: This result has no patch attached. | |
pkg/cli/flags_util.go | |
[ 140] » » return·fmt.Errorf("unknown·key·type·%s",·typ) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg typ for printf verb %s of wrong type: cli.keyType | |
[WARNING][00:17:40] GoVetBear: This result has no patch attached. | |
pkg/sql/information_schema.go | |
[ 207] » » » columndata·:=·privilege.List{privilege.SELECT,·privilege.INSERT,·privilege.UPDATE}·//·privileges·for·column·level·granularity | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! privilege.List composite literal uses unkeyed fields | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 60] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 90] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 118] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 144] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 173] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 210] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 242] » » » » » sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 380] » » OutputOrdering:·convertToSpecOrdering(sqlbase.ColumnOrdering{{ColIdx:·0,·Direction:·encoding.Ascending}}), | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/sorter_test.go | |
[ 425] » » OutputOrdering:·convertToSpecOrdering(sqlbase.ColumnOrdering{{ColIdx:·0,·Direction:·encoding.Ascending}}), | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
[WARNING][00:17:42] GoVetBear: This result has no patch attached. | |
pkg/sql/show_histogram.go | |
[ 111] » » » » row·:=·tree.Datums{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
[WARNING][00:17:43] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:43] GoVetBear: This result has no patch attached. | |
pkg/sql/join.go | |
[ 103] » » » » sqlbase.MultiSourceInfo{pred.info}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.MultiSourceInfo composite literal uses unkeyed fields | |
pkg/sql/join.go | |
[ 243] » » sourceInfo:·sqlbase.MultiSourceInfo{pred.info}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.MultiSourceInfo composite literal uses unkeyed fields | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:44] GoVetBear: This result has no patch attached. | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 95] » » » » » Cols:···types.TTuple{t}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 156] » Cols:···types.TTuple{types.String,·types.String,·types.String}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 221] » Cols:···types.TTuple{types.Int}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 226] » Cols:···types.TTuple{types.Timestamp}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 361] » » Cols:···types.TTuple{s.array.ParamTyp}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 462] » Cols:···types.TTuple{types.JSON}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 467] » Cols:···types.TTuple{types.String}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 554] » Cols:···types.TTuple{types.String}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 620] » Cols:···types.TTuple{types.String,·types.JSON}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/generator_builtins.go | |
[ 625] » Cols:···types.TTuple{types.String,·types.String}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! types.TTuple composite literal uses unkeyed fields | |
[WARNING][00:17:47] GoVetBear: This result has no patch attached. | |
pkg/roachpb/gen_batch.go | |
[ 18] //·+build·gen-batch | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! invalid non-alphanumeric build constraint: gen-batch | |
**** GofmtBear [Section <empty> | Severity NORMAL] **** | |
! ! Formatting can be improved. | |
[----] /home/palash25/Dev/cockroach/pkg/sql/sem/tree/name_resolution_test.go | |
[++++] /home/palash25/Dev/cockroach/pkg/sql/sem/tree/name_resolution_test.go | |
[ 1] // Copyright 2018 The Cockroach Authors. | |
[ 2] // | |
[ 3] // Licensed under the Apache License, Version 2.0 (the "License"); | |
[ 4] // you may not use this file except in compliance with the License. | |
[ 5] // You may obtain a copy of the License at | |
[ 6] // | |
[ 7] // http://www.apache.org/licenses/LICENSE-2.0 | |
[ 8] // | |
[ 9] // Unless required by applicable law or agreed to in writing, software | |
[ 10] // distributed under the License is distributed on an "AS IS" BASIS, | |
[ 11] // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
[ 12] // implied. See the License for the specific language governing | |
[ 13] // permissions and limitations under the License. | |
[ 14] | |
[ 15] package tree_test | |
[ 16] | |
[ 17] import ( | |
[ 18] "context" | |
[ 19] "fmt" | |
[ 20] "testing" | |
[ 21] | |
[ 22] "github.com/cockroachdb/cockroach/pkg/sql/parser" | |
[ 23] "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" | |
[ 24] "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" | |
[ 25] "github.com/cockroachdb/cockroach/pkg/testutils" | |
[ 26] ) | |
[ 27] | |
[ 28] func TestNormalizeTableName(t *testing.T) { | |
[ 29] testCases := []struct { | |
[ 30] in, out string | |
[ 31] expanded string | |
[ 32] err string | |
[ 33] }{ | |
[ 34] {`a`, `a`, `""."".a`, ``}, | |
[ 35] {`a.b`, `a.b`, `"".a.b`, ``}, | |
[ 36] {`a.b.c`, `a.b.c`, `a.b.c`, ``}, | |
[ 37] {`a.b.c.d`, ``, ``, `syntax error at or near "\."`}, | |
[ 38] {`a.""`, ``, ``, `invalid table name: a\.""`}, | |
[ 39] {`a.b.""`, ``, ``, `invalid table name: a\.b\.""`}, | |
[ 40] {`a.b.c.""`, ``, ``, `syntax error at or near "\."`}, | |
[ 41] {`a."".c`, ``, ``, `invalid table name: a\.""\.c`}, | |
[ 42] | |
[ 43] // CockroachDB extension: empty catalog name. | |
[ 44] {`"".b.c`, `"".b.c`, `"".b.c`, ``}, | |
[ 45] | |
[ 46] // Check keywords: disallowed in first position, ok afterwards. | |
[ 47] {`user.x.y`, ``, ``, `syntax error`}, | |
[ 48] {`"user".x.y`, `"user".x.y`, `"user".x.y`, ``}, | |
[ 49] {`x.user.y`, `x."user".y`, `x."user".y`, ``}, | |
[ 50] {`x.user`, `x."user"`, `"".x."user"`, ``}, | |
[ 51] | |
[ 52] {`foo@bar`, ``, ``, `syntax error at or near "@"`}, | |
[ 53] {`test.*`, ``, ``, `syntax error at or near "\*"`}, | |
[ 54] } | |
[ 55] | |
[ 56] for _, tc := range testCases { | |
[ 57] t.Run(tc.in, func(t *testing.T) { | |
[ 58] tn, err := func() (*tree.TableName, error) { | |
[ 59] stmt, err := parser.ParseOne(fmt.Sprintf("ALTER TABLE %s RENAME TO x", tc.in)) | |
[ 60] if err != nil { | |
[ 61] return nil, err | |
[ 62] } | |
[ 63] tn, err := stmt.(*tree.RenameTable).Name.Normalize() | |
[ 64] if err != nil { | |
[ 65] return nil, err | |
[ 66] } | |
[ 67] return tn, nil | |
[ 68] }() | |
[ 69] if !testutils.IsError(err, tc.err) { | |
[ 70] t.Fatalf("%s: expected %s, but found %v", tc.in, tc.err, err) | |
[ 71] } | |
[ 72] if tc.err != "" { | |
[ 73] return | |
[ 74] } | |
[ 75] if out := tn.String(); tc.out != out { | |
[ 76] t.Fatalf("%s: expected %s, but found %s", tc.in, tc.out, out) | |
[ 77] } | |
[ 78] tn.ExplicitSchema = true | |
[ 79] tn.ExplicitCatalog = true | |
[ 80] if out := tn.String(); tc.expanded != out { | |
[ 81] t.Fatalf("%s: expected full %s, but found %s", tc.in, tc.expanded, out) | |
[ 82] } | |
[ 83] }) | |
[ 84] } | |
[ 85] } | |
[ 86] | |
[ 87] func TestClassifyTablePattern(t *testing.T) { | |
[ 88] testCases := []struct { | |
[ 89] in, out string | |
[ 90] expanded string | |
[ 91] err string | |
[ 92] }{ | |
[ 93] {`a`, `a`, `""."".a`, ``}, | |
[ 94] {`a.b`, `a.b`, `"".a.b`, ``}, | |
[ 95] {`a.b.c`, `a.b.c`, `a.b.c`, ``}, | |
[ 96] {`a.b.c.d`, ``, ``, `syntax error at or near "\."`}, | |
[ 97] {`a.""`, ``, ``, `invalid table name: a\.""`}, | |
[ 98] {`a.b.""`, ``, ``, `invalid table name: a\.b\.""`}, | |
[ 99] {`a.b.c.""`, ``, ``, `syntax error at or near "\."`}, | |
[ 100] {`a."".c`, ``, ``, `invalid table name: a\.""\.c`}, | |
[ 101] // CockroachDB extension: empty catalog name. | |
[ 102] {`"".b.c`, `"".b.c`, `"".b.c`, ``}, | |
[ 103] | |
[ 104] // Check keywords: disallowed in first position, ok afterwards. | |
[ 105] {`user.x.y`, ``, ``, `syntax error`}, | |
[ 106] {`"user".x.y`, `"user".x.y`, `"user".x.y`, ``}, | |
[ 107] {`x.user.y`, `x."user".y`, `x."user".y`, ``}, | |
[ 108] {`x.user`, `x."user"`, `"".x."user"`, ``}, | |
[ 109] | |
[ 110] {`*`, `*`, `""."".*`, ``}, | |
[ 111] {`a.*`, `a.*`, `"".a.*`, ``}, | |
[ 112] {`a.b.*`, `a.b.*`, `a.b.*`, ``}, | |
[ 113] {`a.b.c.*`, ``, ``, `syntax error at or near "\."`}, | |
[ 114] {`a.b.*.c`, ``, ``, `syntax error at or near "\."`}, | |
[ 115] {`a.*.b`, ``, ``, `syntax error at or near "\."`}, | |
[ 116] {`*.b`, ``, ``, `syntax error at or near "\."`}, | |
[ 117] {`"".*`, ``, ``, `invalid table name: "".\*`}, | |
[ 118] {`a."".*`, ``, ``, `invalid table name: a\.""\.\*`}, | |
[ 119] {`a.b."".*`, ``, ``, `syntax error at or near "\."`}, | |
[ 120] // CockroachDB extension: empty catalog name. | |
[ 121] {`"".b.*`, `"".b.*`, `"".b.*`, ``}, | |
[ 122] | |
[ 123] // Check keywords: disallowed in first position, ok afterwards. | |
[ 124] {`user.x.*`, ``, ``, `syntax error`}, | |
[ 125] {`"user".x.*`, `"user".x.*`, `"user".x.*`, ``}, | |
[ 126] {`x.user.*`, `x."user".*`, `x."user".*`, ``}, | |
[ 127] | |
[ 128] {`foo@bar`, ``, ``, `syntax error at or near "@"`}, | |
[ 129] } | |
[ 130] | |
[ 131] for _, tc := range testCases { | |
[ 132] t.Run(tc.in, func(t *testing.T) { | |
[ 133] tp, err := func() (tree.TablePattern, error) { | |
[ 134] stmt, err := parser.ParseOne(fmt.Sprintf("GRANT SELECT ON %s TO foo", tc.in)) | |
[ 135] if err != nil { | |
[ 136] return nil, err | |
[ 137] } | |
[ 138] tp, err := stmt.(*tree.Grant).Targets.Tables[0].NormalizeTablePattern() | |
[ 139] if err != nil { | |
[ 140] return nil, err | |
[ 141] } | |
[ 142] return tp, nil | |
[ 143] }() | |
[ 144] if !testutils.IsError(err, tc.err) { | |
[ 145] t.Fatalf("%s: expected %s, but found %v", tc.in, tc.err, err) | |
[ 146] } | |
[ 147] if tc.err != "" { | |
[ 148] return | |
[ 149] } | |
[ 150] if out := tp.String(); tc.out != out { | |
[ 151] t.Fatalf("%s: expected %s, but found %s", tc.in, tc.out, out) | |
[ 152] } | |
[ 153] switch tpv := tp.(type) { | |
[ 154] case *tree.AllTablesSelector: | |
[ 155] tpv.ExplicitSchema = true | |
[ 156] tpv.ExplicitCatalog = true | |
[ 157] case *tree.TableName: | |
[ 158] tpv.ExplicitSchema = true | |
[ 159] tpv.ExplicitCatalog = true | |
[ 160] default: | |
[ 161] t.Fatalf("%s: unknown pattern type: %T", tc.in, tp) | |
[ 162] } | |
[ 163] | |
[ 164] if out := tp.String(); tc.expanded != out { | |
[ 165] t.Fatalf("%s: expected full %s, but found %s", tc.in, tc.expanded, out) | |
[ 166] } | |
[ 167] }) | |
[ 168] } | |
[ 169] } | |
[ 170] | |
[ 171] func TestClassifyColumnName(t *testing.T) { | |
[ 172] testCases := []struct { | |
[ 173] in, out string | |
[ 174] err string | |
[ 175] }{ | |
[ 176] {`a`, `a`, ``}, | |
[ 177] {`a.b`, `a.b`, ``}, | |
[ 178] {`a.b.c`, `a.b.c`, ``}, | |
[ 179] {`a.b.c.d`, `a.b.c.d`, ``}, | |
[ 180] {`a.b.c.d.e`, ``, `syntax error at or near "\."`}, | |
[ 181] {`""`, ``, `invalid column name: ""`}, | |
[ 182] {`a.""`, ``, `invalid column name: a\.""`}, | |
[ 183] {`a.b.""`, ``, `invalid column name: a\.b\.""`}, | |
[ 184] {`a.b.c.""`, ``, `invalid column name: a\.b\.c\.""`}, | |
[ 185] {`a.b.c.d.""`, ``, `syntax error at or near "\."`}, | |
[ 186] {`"".a`, ``, `invalid column name: ""\.a`}, | |
[ 187] {`"".a.b`, ``, `invalid column name: ""\.a\.b`}, | |
[ 188] // CockroachDB extension: empty catalog name. | |
[ 189] {`"".a.b.c`, `"".a.b.c`, ``}, | |
[ 190] | |
[ 191] {`a.b."".d`, ``, `invalid column name: a\.b\.""\.d`}, | |
[ 192] {`a."".c.d`, ``, `invalid column name: a\.""\.c\.d`}, | |
[ 193] | |
[ 194] // Check keywords: disallowed in first position, ok afterwards. | |
[ 195] {`user.x.y`, ``, `syntax error`}, | |
[ 196] {`"user".x.y`, `"user".x.y`, ``}, | |
[ 197] {`x.user.y`, `x.user.y`, ``}, | |
[ 198] {`x.user`, `x."user"`, ``}, | |
[ 199] | |
[ 200] {`*`, `*`, ``}, | |
[ 201] {`a.*`, `a.*`, ``}, | |
[ 202] {`a.b.*`, `a.b.*`, ``}, | |
[ 203] {`a.b.c.*`, `a.b.c.*`, ``}, | |
[ 204] {`a.b.c.d.*`, ``, `syntax error at or near "\."`}, | |
[ 205] {`a.b.*.c`, ``, `syntax error at or near "\."`}, | |
[ 206] {`a.*.b`, ``, `syntax error at or near "\."`}, | |
[ 207] {`*.b`, ``, `syntax error at or near "\."`}, | |
[ 208] {`"".*`, ``, `invalid column name: "".\*`}, | |
[ 209] {`a."".*`, ``, `invalid column name: a\.""\.\*`}, | |
[ 210] {`a.b."".*`, ``, `invalid column name: a\.b\.""\.\*`}, | |
[ 211] {`a.b.c."".*`, ``, `syntax error at or near "\."`}, | |
[ 212] | |
[ 213] {`"".a.*`, ``, `invalid column name: ""\.a.*`}, | |
[ 214] // CockroachDB extension: empty catalog name. | |
[ 215] {`"".a.b.*`, `"".a.b.*`, ``}, | |
[ 216] | |
[ 217] {`a."".c.*`, ``, `invalid column name: a\.""\.c\.*`}, | |
[ 218] | |
[ 219] // Check keywords: disallowed in first position, ok afterwards. | |
[ 220] {`user.x.*`, ``, `syntax error`}, | |
[ 221] {`"user".x.*`, `"user".x.*`, ``}, | |
[ 222] {`x.user.*`, `x.user.*`, ``}, | |
[ 223] | |
[ 224] {`foo@bar`, ``, `syntax error at or near "@"`}, | |
[ 225] } | |
[ 226] | |
[ 227] for _, tc := range testCases { | |
[ 228] t.Run(tc.in, func(t *testing.T) { | |
[ 229] v, err := func() (tree.VarName, error) { | |
[ 230] stmt, err := parser.ParseOne(fmt.Sprintf("SELECT %s", tc.in)) | |
[ 231] if err != nil { | |
[ 232] return nil, err | |
[ 233] } | |
[ 234] v := stmt.(*tree.Select).Select.(*tree.SelectClause).Exprs[0].Expr.(tree.VarName) | |
[ 235] return v.NormalizeVarName() | |
[ 236] }() | |
[ 237] if !testutils.IsError(err, tc.err) { | |
[ 238] t.Fatalf("%s: expected %s, but found %v", tc.in, tc.err, err) | |
[ 239] } | |
[ 240] if tc.err != "" { | |
[ 241] return | |
[ 242] } | |
[ 243] if out := v.String(); tc.out != out { | |
[ 244] t.Fatalf("%s: expected %s, but found %s", tc.in, tc.out, out) | |
[ 245] } | |
[ 246] switch v.(type) { | |
[ 247] case *tree.AllColumnsSelector: | |
[ 248] case tree.UnqualifiedStar: | |
[ 249] case *tree.ColumnItem: | |
[ 250] default: | |
[ 251] t.Fatalf("%s: unknown var type: %T", tc.in, v) | |
[ 252] } | |
[ 253] }) | |
[ 254] } | |
[ 255] } | |
[ 256] | |
[ 257] // fakeSource represents a fake column resolution environment for tests. | |
[ 258] type fakeSource struct { | |
[ 259] t *testing.T | |
[ 260] knownTables knownTableList | |
[ 261] } | |
[ 262] | |
[ 263] type knownTableList []struct { | |
[ 264] srcName tree.TableName | |
[ 265] columns []tree.Name | |
[ 266] } | |
[ 267] | |
[ 268] type colsRes tree.NameList | |
[ 269] | |
[ 270] func (c colsRes) ColumnSourceMeta() {} | |
[ 271] | |
[ 272] // FindSourceMatchingName implements the ColumnItemResolver interface. | |
[ 273] func (f *fakeSource) FindSourceMatchingName( | |
[ 274] _ context.Context, tn tree.TableName, | |
[ 275] ) ( | |
[ 276] res tree.NumResolutionResults, | |
[ 277] prefix *tree.TableName, | |
[ 278] srcMeta tree.ColumnSourceMeta, | |
[ 279] err error, | |
[ 280] ) { | |
[ 281] defer func() { | |
[ 282] f.t.Logf("FindSourceMatchingName(%s) -> res %d prefix %s meta %v err %v", | |
[ 283] &tn, res, prefix, srcMeta, err) | |
[ 284] }() | |
[ 285] found := false | |
[ 286] var columns colsRes | |
[ 287] for i := range f.knownTables { | |
[ 288] t := &f.knownTables[i] | |
[ 289] if t.srcName.TableName != tn.TableName { | |
[ 290] continue | |
[ 291] } | |
[ 292] if tn.ExplicitSchema { | |
[ 293] if !t.srcName.ExplicitSchema || t.srcName.SchemaName != tn.SchemaName { | |
[ 294] continue | |
[ 295] } | |
[ 296] if tn.ExplicitCatalog { | |
[ 297] if !t.srcName.ExplicitCatalog || t.srcName.CatalogName != tn.CatalogName { | |
[ 298] continue | |
[ 299] } | |
[ 300] } | |
[ 301] } | |
[ 302] if found { | |
[ 303] return tree.MoreThanOne, nil, nil, fmt.Errorf("ambiguous table name: %s", &tn) | |
[ 304] } | |
[ 305] found = true | |
[ 306] prefix = &t.srcName | |
[ 307] columns = colsRes(t.columns) | |
[ 308] } | |
[ 309] if !found { | |
[ 310] return tree.NoResults, nil, nil, nil | |
[ 311] } | |
[ 312] return tree.ExactlyOne, prefix, columns, nil | |
[ 313] } | |
[ 314] | |
[ 315] // FindSourceProvidingColumn implements the ColumnItemResolver interface. | |
[ 316] func (f *fakeSource) FindSourceProvidingColumn( | |
[ 317] _ context.Context, col tree.Name, | |
[ 318] ) (prefix *tree.TableName, srcMeta tree.ColumnSourceMeta, colHint int, err error) { | |
[ 319] defer func() { | |
[ 320] f.t.Logf("FindSourceProvidingColumn(%s) -> prefix %s meta %v hint %d err %v", | |
[ 321] col, prefix, srcMeta, colHint, err) | |
[ 322] }() | |
[ 323] found := false | |
[ 324] var columns colsRes | |
[ 325] for i := range f.knownTables { | |
[ 326] t := &f.knownTables[i] | |
[ 327] for c, cn := range t.columns { | |
[ 328] if cn != col { | |
[ 329] continue | |
[ 330] } | |
[ 331] if found { | |
[ 332] return nil, nil, -1, fmt.Errorf("ambiguous column name: %s", &col) | |
[ 333] } | |
[ 334] found = true | |
[ 335] colHint = c | |
[ 336] columns = colsRes(t.columns) | |
[ 337] prefix = &t.srcName | |
[ 338] break | |
[ 339] } | |
[ 340] } | |
[ 341] if !found { | |
[ 342] return nil, nil, -1, fmt.Errorf("unknown column name: %s", &col) | |
[ 343] } | |
[ 344] return prefix, columns, colHint, nil | |
[ 345] } | |
[ 346] | |
[ 347] type colRes string | |
[ 348] | |
[ 349] func (c colRes) ColumnResolutionResult() {} | |
[ 350] | |
[ 351] // Resolve implements the ColumnItemResolver interface. | |
[ 352] func (f *fakeSource) Resolve( | |
[ 353] _ context.Context, | |
[ 354] prefix *tree.TableName, | |
[ 355] srcMeta tree.ColumnSourceMeta, | |
[ 356] colHint int, | |
[ 357] col tree.Name, | |
[ 358] ) (tree.ColumnResolutionResult, error) { | |
[ 359] f.t.Logf("in Resolve: prefix %s meta %v colHint %d col %s", | |
[ 360] prefix, srcMeta, colHint, col) | |
[ 361] columns, ok := srcMeta.(colsRes) | |
[ 362] if !ok { | |
[ 363] return nil, fmt.Errorf("programming error: srcMeta invalid") | |
[ 364] } | |
[ 365] if colHint >= 0 { | |
[ 366] // Resolution succeeded. Let's do some sanity checking. | |
[ 367] if columns[colHint] != col { | |
[ 368] return nil, fmt.Errorf("programming error: invalid colHint %d", colHint) | |
[ 369] } | |
[ 370] return colRes(fmt.Sprintf("%s.%s(%d)", prefix, col, colHint)), nil | |
[ 371] } | |
[ 372] for c, cn := range columns { | |
[ 373] if col == cn { | |
[ 374] // Resolution succeeded. | |
[ 375] return colRes(fmt.Sprintf("%s.%s(%d)", prefix, col, c)), nil | |
[ 376] } | |
[ 377] } | |
[ 378] return nil, fmt.Errorf("unknown column name: %s", &col) | |
[ 379] } | |
[ 380] | |
[ 381] func newFakeSource() *fakeSource { | |
[ 382] return &fakeSource{ | |
[ 383] knownTables: knownTableList{ | |
[ 384] {tree.MakeTableNameWithSchema("", "crdb_internal", "tables"), []tree.Name{"table_name"}}, | |
[ 385] {tree.MakeTableName("db1", "foo"), []tree.Name{"x"}}, | |
[ 386] {tree.MakeTableName("db2", "foo"), []tree.Name{"x"}}, | |
[ 387] {tree.MakeUnqualifiedTableName("bar"), []tree.Name{"x"}}, | |
[ 388] {tree.MakeTableName("db1", "kv"), []tree.Name{"k", "v"}}, | |
[ 389] }, | |
[ 390] } | |
[ 391] } | |
[ 392] | |
[ 393] func TestResolveColumnItem(t *testing.T) { | |
[ 394] testCases := []struct { | |
[ 395] in string | |
[ 396] out string | |
[ 397] err string | |
[ 398] }{ | |
[ 399] {`a`, ``, `unknown column name`}, | |
[ 400] {`x`, ``, `ambiguous column name`}, | |
[ 401] {`k`, `db1.public.kv.k(0)`, ``}, | |
[ 402] {`v`, `db1.public.kv.v(1)`, ``}, | |
[ 403] {`table_name`, `"".crdb_internal.tables.table_name(0)`, ``}, | |
[ 404] | |
[ 405] {`blix.x`, ``, `no data source matches prefix: blix`}, | |
[ 406] {`"".x`, ``, `invalid column name: ""\.x`}, | |
[ 407] {`foo.x`, ``, `ambiguous table name`}, | |
[ 408] {`kv.k`, `db1.public.kv.k(0)`, ``}, | |
[ 409] {`bar.x`, `bar.x(0)`, ``}, | |
[ 410] {`tables.table_name`, `"".crdb_internal.tables.table_name(0)`, ``}, | |
[ 411] | |
[ 412] {`a.b.x`, ``, `no data source matches prefix: a\.b`}, | |
[ 413] {`crdb_internal.tables.table_name`, `"".crdb_internal.tables.table_name(0)`, ``}, | |
[ 414] {`public.foo.x`, ``, `ambiguous table name`}, | |
[ 415] {`public.kv.k`, `db1.public.kv.k(0)`, ``}, | |
[ 416] | |
[ 417] // CockroachDB extension: d.t.x -> d.public.t.x | |
[ 418] {`db1.foo.x`, `db1.public.foo.x(0)`, ``}, | |
[ 419] {`db2.foo.x`, `db2.public.foo.x(0)`, ``}, | |
[ 420] | |
[ 421] {`a.b.c.x`, ``, `no data source matches prefix: a\.b\.c`}, | |
[ 422] {`"".crdb_internal.tables.table_name`, `"".crdb_internal.tables.table_name(0)`, ``}, | |
[ 423] {`db1.public.foo.x`, `db1.public.foo.x(0)`, ``}, | |
[ 424] {`db2.public.foo.x`, `db2.public.foo.x(0)`, ``}, | |
[ 425] {`db1.public.kv.v`, `db1.public.kv.v(1)`, ``}, | |
[ 426] } | |
[ 427] | |
[ 428] fakeFrom := newFakeSource() | |
[ 429] for _, tc := range testCases { | |
[ 430] t.Run(tc.in, func(t *testing.T) { | |
[ 431] fakeFrom.t = t | |
[ 432] out, err := func() (string, error) { | |
[ 433] stmt, err := parser.ParseOne(fmt.Sprintf("SELECT %s", tc.in)) | |
[ 434] if err != nil { | |
[ 435] return "", err | |
[ 436] } | |
[ 437] v := stmt.(*tree.Select).Select.(*tree.SelectClause).Exprs[0].Expr.(tree.VarName) | |
[ 438] c, err := v.NormalizeVarName() | |
[ 439] if err != nil { | |
[ 440] return "", err | |
[ 441] } | |
[ 442] ci, ok := c.(*tree.ColumnItem) | |
[ 443] if !ok { | |
[ 444] return "", fmt.Errorf("var name %s (%T) did not resolve to ColumnItem, found %T instead", | |
[ 445] v, v, c) | |
[ 446] } | |
[ 447] res, err := ci.Resolve(context.Background(), fakeFrom) | |
[ 448] if err != nil { | |
[ 449] return "", err | |
[ 450] } | |
[ 451] s, ok := res.(colRes) | |
[ 452] if !ok { | |
[ 453] return "", fmt.Errorf("fake resolver did not return colRes, found %T instead", res) | |
[ 454] } | |
[ 455] return string(s), nil | |
[ 456] }() | |
[ 457] if !testutils.IsError(err, tc.err) { | |
[ 458] t.Fatalf("%s: expected %s, but found %v", tc.in, tc.err, err) | |
[ 459] } | |
[ 460] if tc.err != "" { | |
[ 461] return | |
[ 462] } | |
[ 463] | |
[ 464] if tc.out != out { | |
[ 465] t.Fatalf("%s: expected %s, but found %s", tc.in, tc.out, out) | |
[ 466] } | |
[ 467] }) | |
[ 468] } | |
[ 469] } | |
[ 470] | |
[ 471] // fakeMetadata represents a fake table resolution environment for tests. | |
[ 472] type fakeMetadata struct { | |
[ 473] t *testing.T | |
[ 474] knownVSchemas []knownSchema | |
[ 475] knownCatalogs []knownCatalog | |
[ 476] } | |
[ 477] | |
[ 478] type knownSchema struct { | |
[ 479] scName tree.Name | |
[ 480] tables []tree.Name | |
[ 481] } | |
[ 482] | |
[ 483] func (*knownSchema) SchemaMeta() {} | |
[ 484] | |
[ 485] type knownCatalog struct { | |
[ 486] ctName tree.Name | |
[ 487] schemas []knownSchema | |
[ 488] } | |
[ 489] | |
[ 490] // LookupSchema implements the TableNameResolver interface. | |
[ 491] func (f *fakeMetadata) LookupSchema( | |
[ 492] _ context.Context, dbName, scName string, | |
[ 493] ) (found bool, scMeta tree.SchemaMeta, err error) { | |
[ 494] defer func() { | |
[ 495] f.t.Logf("LookupSchema(%s, %s) -> found %v meta %v err %v", | |
[ 496] dbName, scName, found, scMeta, err) | |
[ 497] }() | |
[ 498] for i := range f.knownVSchemas { | |
[ 499] v := &f.knownVSchemas[i] | |
[ 500] if scName == string(v.scName) { | |
[ 501] // Virtual schema found, check that the db exists. | |
[ 502] // The empty database is valid. | |
[ 503] if dbName == "" { | |
[ 504] return true, v, nil | |
[ 505] } | |
[ 506] for j := range f.knownCatalogs { | |
[ 507] c := &f.knownCatalogs[j] | |
[ 508] if dbName == string(c.ctName) { | |
[ 509] return true, v, nil | |
[ 510] } | |
[ 511] } | |
[ 512] // No valid database, schema is invalid. | |
[ 513] return false, nil, nil | |
[ 514] } | |
[ 515] } | |
[ 516] for i := range f.knownCatalogs { | |
[ 517] c := &f.knownCatalogs[i] | |
[ 518] if dbName == string(c.ctName) { | |
[ 519] for j := range c.schemas { | |
[ 520] s := &c.schemas[j] | |
[ 521] if scName == string(s.scName) { | |
[ 522] return true, s, nil | |
[ 523] } | |
[ 524] } | |
[ 525] break | |
[ 526] } | |
[ 527] } | |
[ 528] return false, nil, nil | |
[ 529] } | |
[ 530] | |
[ 531] type fakeResResult int | |
[ 532] | |
[ 533] func (fakeResResult) NameResolutionResult() {} | |
[ 534] | |
[ 535] // LookupObject implements the TableNameResolver interface. | |
[ 536] func (f *fakeMetadata) LookupObject( | |
[ 537] _ context.Context, dbName, scName, tbName string, | |
[ 538] ) (found bool, obMeta tree.NameResolutionResult, err error) { | |
[ 539] defer func() { | |
[ 540] f.t.Logf("LookupObject(%s, %s, %s) -> found %v meta %v err %v", | |
[ 541] dbName, scName, tbName, found, obMeta, err) | |
[ 542] }() | |
[ 543] foundV := false | |
[ 544] for i := range f.knownVSchemas { | |
[ 545] v := &f.knownVSchemas[i] | |
[ 546] if scName == string(v.scName) { | |
[ 547] // Virtual schema found, check that the db exists. | |
[ 548] // The empty database is valid. | |
[ 549] if dbName != "" { | |
[ 550] hasDb := false | |
[ 551] for j := range f.knownCatalogs { | |
[ 552] c := &f.knownCatalogs[j] | |
[ 553] if dbName == string(c.ctName) { | |
[ 554] hasDb = true | |
[ 555] break | |
[ 556] } | |
[ 557] } | |
[ 558] if !hasDb { | |
[ 559] return false, nil, nil | |
[ 560] } | |
[ 561] } | |
[ 562] // Db valid, check the table name. | |
[ 563] for tbIdx, tb := range v.tables { | |
[ 564] if tbName == string(tb) { | |
[ 565] return true, fakeResResult(tbIdx), nil | |
[ 566] } | |
[ 567] } | |
[ 568] foundV = true | |
[ 569] break | |
[ 570] } | |
[ 571] } | |
[ 572] if foundV { | |
[ 573] // Virtual schema matched, but there was no table. Fail. | |
[ 574] return false, nil, nil | |
[ 575] } | |
[ 576] | |
[ 577] for i := range f.knownCatalogs { | |
[ 578] c := &f.knownCatalogs[i] | |
[ 579] if dbName == string(c.ctName) { | |
[ 580] for j := range c.schemas { | |
[ 581] s := &c.schemas[j] | |
[ 582] if scName == string(s.scName) { | |
[ 583] for tbIdx, tb := range s.tables { | |
[ 584] if tbName == string(tb) { | |
[ 585] return true, fakeResResult(tbIdx), nil | |
[ 586] } | |
[ 587] } | |
[ 588] break | |
[ 589] } | |
[ 590] } | |
[ 591] break | |
[ 592] } | |
[ 593] } | |
[ 594] return false, nil, nil | |
[ 595] } | |
[ 596] | |
[ 597] func newFakeMetadata() *fakeMetadata { | |
[ 598] return &fakeMetadata{ | |
[ 599] knownVSchemas: []knownSchema{ | |
[ 600] {"pg_catalog", []tree.Name{"pg_tables"}}, | |
[ 601] }, | |
[ 602] knownCatalogs: []knownCatalog{ | |
[ 603] {"db1", []knownSchema{{"public", []tree.Name{"foo", "kv"}}}}, | |
[ 604] {"db2", []knownSchema{ | |
[ 605] {"public", []tree.Name{"foo"}}, | |
[ 606] {"extended", []tree.Name{"bar", "pg_tables"}}, | |
[ 607] }}, | |
[ 608] }, | |
[ 609] } | |
[ 610] } | |
[ 611] | |
[ 612] func TestResolveTablePatternOrName(t *testing.T) { | |
[ 613] type spath = sessiondata.SearchPath | |
[ 614] | |
[ 615] var mpath = func(args ...string) spath { return sessiondata.MakeSearchPath(args) } | |
[ 616] | |
[ 617] testCases := []struct { | |
[ 618] // Test inputs. | |
[ 619] in string // The table name or pattern. | |
[ 620] curDb string // The current database. | |
[ 621] searchPath spath // The current search path. | |
[ 622] expected bool // If non-star, whether the object is expected to exist already. | |
[ 623] // Expected outputs. | |
[ 624] out string // The prefix after resolution. | |
[ 625] expanded string // The prefix after resolution, with hidden fields revealed. | |
[ 626] scName string // The schema name after resolution. | |
[ 627] err string // Error, if expected. | |
[ 628] }{ | |
[ 629] // | |
[ 630] // Tests for table names. | |
[ 631] // | |
[ 632] | |
[ 633] // Names of length 1. | |
[ 634] | |
[ 635] {`kv`, `db1`, mpath("public", "pg_catalog"), true, `kv`, `db1.public.kv`, `db1.public[1]`, ``}, | |
[ 636] {`foo`, `db1`, mpath("public", "pg_catalog"), true, `foo`, `db1.public.foo`, `db1.public[0]`, ``}, | |
[ 637] {`blix`, `db1`, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 638] {`pg_tables`, `db1`, mpath("public", "pg_catalog"), true, `pg_tables`, `db1.pg_catalog.pg_tables`, `db1.pg_catalog[0]`, ``}, | |
[ 639] | |
[ 640] {`blix`, `db1`, mpath("public", "pg_catalog"), false, `blix`, `db1.public.blix`, `db1.public`, ``}, | |
[ 641] | |
[ 642] // A valid table is invisible if "public" is not in the search path. | |
[ 643] {`kv`, `db1`, mpath(), true, ``, ``, ``, `prefix or object not found`}, | |
[ 644] | |
[ 645] // But pg_catalog is magic and "always there". | |
[ 646] {`pg_tables`, `db1`, mpath(), true, `pg_tables`, `db1.pg_catalog.pg_tables`, `db1.pg_catalog[0]`, ``}, | |
[ 647] {`blix`, `db1`, mpath(), false, ``, ``, ``, `prefix or object not found`}, | |
[ 648] | |
[ 649] // If there's a table with the same name as a pg_catalog table, then search path order matters. | |
[ 650] {`pg_tables`, `db2`, mpath("extended", "pg_catalog"), true, `pg_tables`, `db2.extended.pg_tables`, `db2.extended[1]`, ``}, | |
[ 651] {`pg_tables`, `db2`, mpath("pg_catalog", "extended"), true, `pg_tables`, `db2.pg_catalog.pg_tables`, `db2.pg_catalog[0]`, ``}, | |
[ 652] // When pg_catalog is not explicitly mentioned in the search path, it is searched first. | |
[ 653] {`pg_tables`, `db2`, mpath("foo"), true, `pg_tables`, `db2.pg_catalog.pg_tables`, `db2.pg_catalog[0]`, ``}, | |
[ 654] | |
[ 655] // Names of length 2. | |
[ 656] | |
[ 657] {`public.kv`, `db1`, mpath("public", "pg_catalog"), true, `public.kv`, `db1.public.kv`, `db1.public[1]`, ``}, | |
[ 658] {`public.foo`, `db1`, mpath("public", "pg_catalog"), true, `public.foo`, `db1.public.foo`, `db1.public[0]`, ``}, | |
[ 659] {`public.blix`, `db1`, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 660] {`public.pg_tables`, `db1`, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 661] {`extended.pg_tables`, `db2`, mpath("public", "pg_catalog"), true, `extended.pg_tables`, `db2.extended.pg_tables`, `db2.extended[1]`, ``}, | |
[ 662] {`pg_catalog.pg_tables`, `db1`, mpath("public", "pg_catalog"), true, `pg_catalog.pg_tables`, `db1.pg_catalog.pg_tables`, `db1.pg_catalog[0]`, ``}, | |
[ 663] | |
[ 664] {`public.blix`, `db1`, mpath("public", "pg_catalog"), false, `public.blix`, `db1.public.blix`, `db1.public`, ``}, | |
[ 665] | |
[ 666] // Compat with CockroachDB v1.x. | |
[ 667] {`db1.kv`, `db1`, mpath("public", "pg_catalog"), true, `db1.public.kv`, `db1.public.kv`, `db1.public[1]`, ``}, | |
[ 668] | |
[ 669] {`blix.foo`, `db1`, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 670] {`blix.pg_tables`, `db1`, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 671] | |
[ 672] // Names of length 3. | |
[ 673] | |
[ 674] {`db1.public.foo`, `db1`, mpath("public", "pg_catalog"), true, `db1.public.foo`, `db1.public.foo`, `db1.public[0]`, ``}, | |
[ 675] {`db1.public.kv`, `db1`, mpath(), true, `db1.public.kv`, `db1.public.kv`, `db1.public[1]`, ``}, | |
[ 676] {`db1.public.blix`, `db1`, mpath(), false, `db1.public.blix`, `db1.public.blix`, `db1.public`, ``}, | |
[ 677] | |
[ 678] {`blix.public.foo`, `db1`, mpath("public"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 679] {`blix.public.foo`, `db1`, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 680] | |
[ 681] // Beware: vtables only exist in valid databases and the empty database name. | |
[ 682] {`db1.pg_catalog.pg_tables`, `db1`, mpath(), true, `db1.pg_catalog.pg_tables`, `db1.pg_catalog.pg_tables`, `db1.pg_catalog[0]`, ``}, | |
[ 683] {`"".pg_catalog.pg_tables`, `db1`, mpath(), true, `"".pg_catalog.pg_tables`, `"".pg_catalog.pg_tables`, `.pg_catalog[0]`, ``}, | |
[ 684] {`blix.pg_catalog.pg_tables`, `db1`, mpath("public"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 685] {`blix.pg_catalog.pg_tables`, `db1`, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 686] {`"".pg_catalog.blix`, `db1`, mpath(), false, `"".pg_catalog.blix`, `"".pg_catalog.blix`, `.pg_catalog`, ``}, | |
[ 687] | |
[ 688] // | |
[ 689] // Tests for table names with no current database. | |
[ 690] // | |
[ 691] | |
[ 692] {`kv`, ``, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 693] {`pg_tables`, ``, mpath("public", "pg_catalog"), true, `pg_tables`, `"".pg_catalog.pg_tables`, `.pg_catalog[0]`, ``}, | |
[ 694] {`pg_tables`, ``, mpath(), true, `pg_tables`, `"".pg_catalog.pg_tables`, `.pg_catalog[0]`, ``}, | |
[ 695] | |
[ 696] {`blix`, ``, mpath("public", "pg_catalog"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 697] | |
[ 698] // Names of length 2. | |
[ 699] | |
[ 700] {`public.kv`, ``, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 701] {`pg_catalog.pg_tables`, ``, mpath("public", "pg_catalog"), true, `pg_catalog.pg_tables`, `"".pg_catalog.pg_tables`, `.pg_catalog[0]`, ``}, | |
[ 702] | |
[ 703] // Compat with CockroachDB v1.x. | |
[ 704] {`db1.kv`, ``, mpath("public", "pg_catalog"), true, `db1.public.kv`, `db1.public.kv`, `db1.public[1]`, ``}, | |
[ 705] {`db1.blix`, ``, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 706] | |
[ 707] {`blix.pg_tables`, ``, mpath("public", "pg_catalog"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 708] | |
[ 709] // Names of length 3. | |
[ 710] | |
[ 711] {`db1.public.foo`, ``, mpath("public", "pg_catalog"), true, `db1.public.foo`, `db1.public.foo`, `db1.public[0]`, ``}, | |
[ 712] {`db1.public.kv`, ``, mpath(), true, `db1.public.kv`, `db1.public.kv`, `db1.public[1]`, ``}, | |
[ 713] {`db1.public.blix`, ``, mpath(), false, `db1.public.blix`, `db1.public.blix`, `db1.public`, ``}, | |
[ 714] | |
[ 715] {`blix.public.foo`, ``, mpath("public"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 716] {`blix.public.foo`, ``, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 717] | |
[ 718] // Beware: vtables only exist in valid databases and the empty database name. | |
[ 719] {`db1.pg_catalog.pg_tables`, ``, mpath(), true, `db1.pg_catalog.pg_tables`, `db1.pg_catalog.pg_tables`, `db1.pg_catalog[0]`, ``}, | |
[ 720] {`"".pg_catalog.pg_tables`, ``, mpath(), true, `"".pg_catalog.pg_tables`, `"".pg_catalog.pg_tables`, `.pg_catalog[0]`, ``}, | |
[ 721] {`blix.pg_catalog.pg_tables`, ``, mpath("public"), true, ``, ``, ``, `prefix or object not found`}, | |
[ 722] {`blix.pg_catalog.pg_tables`, ``, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 723] {`"".pg_catalog.blix`, ``, mpath(), false, `"".pg_catalog.blix`, `"".pg_catalog.blix`, `.pg_catalog`, ``}, | |
[ 724] | |
[ 725] // | |
[ 726] // Tests for table patterns. | |
[ 727] // | |
[ 728] | |
[ 729] // Patterns of length 1. | |
[ 730] | |
[ 731] {`*`, `db1`, mpath("public", "pg_catalog"), false, `*`, `db1.public.*`, `db1.public`, ``}, | |
[ 732] | |
[ 733] // Patterns of length 2. | |
[ 734] {`public.*`, `db1`, mpath("public"), false, `public.*`, `db1.public.*`, `db1.public`, ``}, | |
[ 735] {`public.*`, `db1`, mpath("public", "pg_catalog"), false, `public.*`, `db1.public.*`, `db1.public`, ``}, | |
[ 736] {`public.*`, `db1`, mpath(), false, `public.*`, `db1.public.*`, `db1.public`, ``}, | |
[ 737] | |
[ 738] {`blix.*`, `db1`, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 739] | |
[ 740] {`pg_catalog.*`, `db1`, mpath("public"), false, `pg_catalog.*`, `db1.pg_catalog.*`, `db1.pg_catalog`, ``}, | |
[ 741] {`pg_catalog.*`, `db1`, mpath("public", "pg_catalog"), false, `pg_catalog.*`, `db1.pg_catalog.*`, `db1.pg_catalog`, ``}, | |
[ 742] {`pg_catalog.*`, `db1`, mpath(), false, `pg_catalog.*`, `db1.pg_catalog.*`, `db1.pg_catalog`, ``}, | |
[ 743] | |
[ 744] // | |
[ 745] // Tests for table patterns with no current database. | |
[ 746] // | |
[ 747] | |
[ 748] // Patterns of length 1. | |
[ 749] | |
[ 750] {`*`, ``, mpath("public", "pg_catalog"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 751] | |
[ 752] // Patterns of length 2. | |
[ 753] | |
[ 754] {`public.*`, ``, mpath("public", "pg_catalog"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 755] // vtables exist also in the empty database. | |
[ 756] {`pg_catalog.*`, ``, mpath("public", "pg_catalog"), false, `pg_catalog.*`, `"".pg_catalog.*`, `.pg_catalog`, ``}, | |
[ 757] {`pg_catalog.*`, ``, mpath(), false, `pg_catalog.*`, `"".pg_catalog.*`, `.pg_catalog`, ``}, | |
[ 758] | |
[ 759] // Compat with CockroachDB v1.x. | |
[ 760] {`db1.*`, ``, mpath("public", "pg_catalog"), false, `db1.public.*`, `db1.public.*`, `db1.public`, ``}, | |
[ 761] | |
[ 762] {`blix.*`, ``, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 763] {`blix.*`, ``, mpath("public", "pg_catalog"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 764] {`blix.*`, ``, mpath(), false, ``, ``, ``, `prefix or object not found`}, | |
[ 765] | |
[ 766] // Patterns of length 3. | |
[ 767] | |
[ 768] {`db1.public.*`, ``, mpath("public", "pg_catalog"), false, `db1.public.*`, `db1.public.*`, `db1.public`, ``}, | |
[ 769] {`db1.public.*`, ``, mpath(), false, `db1.public.*`, `db1.public.*`, `db1.public`, ``}, | |
[ 770] | |
[ 771] {`blix.public.*`, ``, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 772] {`blix.public.*`, ``, mpath("public", "pg_catalog"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 773] | |
[ 774] // Beware: vtables only exist in valid databases and the empty database name. | |
[ 775] {`db1.pg_catalog.*`, ``, mpath(), false, `db1.pg_catalog.*`, `db1.pg_catalog.*`, `db1.pg_catalog`, ``}, | |
[ 776] {`"".pg_catalog.*`, ``, mpath(), false, `"".pg_catalog.*`, `"".pg_catalog.*`, `.pg_catalog`, ``}, | |
[ 777] {`blix.pg_catalog.*`, ``, mpath("public"), false, ``, ``, ``, `prefix or object not found`}, | |
[ 778] } | |
[ 779] | |
[ 780] fakeResolver := newFakeMetadata() | |
[ 781] for _, tc := range testCases { | |
[ 782] t.Run(fmt.Sprintf("%s/%s/%s/%v", tc.in, tc.curDb, tc.searchPath, tc.expected), func(t *testing.T) { | |
[ 783] fakeResolver.t = t | |
[ 784] tp, sc, err := func() (tree.TablePattern, string, error) { | |
[ 785] stmt, err := parser.ParseOne(fmt.Sprintf("GRANT SELECT ON TABLE %s TO foo", tc.in)) | |
[ 786] if err != nil { | |
[ 787] return nil, "", err | |
[ 788] } | |
[ 789] tp, err := stmt.(*tree.Grant).Targets.Tables[0].NormalizeTablePattern() | |
[ 790] if err != nil { | |
[ 791] return nil, "", err | |
[ 792] } | |
[ 793] | |
[ 794] var found bool | |
[ 795] var scPrefix, ctPrefix string | |
[ 796] var scMeta interface{} | |
[ 797] var obMeta interface{} | |
[ 798] ctx := context.Background() | |
[ 799] switch tpv := tp.(type) { | |
[ 800] case *tree.AllTablesSelector: | |
[ 801] found, scMeta, err = tpv.TableNamePrefix.Resolve(ctx, fakeResolver, tc.curDb, tc.searchPath) | |
[ 802] scPrefix = tpv.Schema() | |
[ 803] ctPrefix = tpv.Catalog() | |
[ 804] case *tree.TableName: | |
[ 805] if tc.expected { | |
[ 806] found, obMeta, err = tpv.ResolveExisting(ctx, fakeResolver, tc.curDb, tc.searchPath) | |
[ 807] } else { | |
[ 808] found, scMeta, err = tpv.ResolveTarget(ctx, fakeResolver, tc.curDb, tc.searchPath) | |
[ 809] } | |
[ 810] scPrefix = tpv.Schema() | |
[ 811] ctPrefix = tpv.Catalog() | |
[ 812] default: | |
[ 813] t.Fatalf("%s: unknown pattern type: %T", t.Name(), tp) | |
[ 814] } | |
[ 815] if err != nil { | |
[ 816] return nil, "", err | |
[ 817] } | |
[ 818] | |
[ 819] var scRes string | |
[ 820] if scMeta != nil { | |
[ 821] sc, ok := scMeta.(*knownSchema) | |
[ 822] if !ok { | |
[ 823] t.Fatalf("%s: scMeta not of correct type: %v", t.Name(), scMeta) | |
[ 824] } | |
[ 825] scRes = fmt.Sprintf("%s.%s", ctPrefix, sc.scName) | |
[ 826] } | |
[ 827] if obMeta != nil { | |
[ 828] obIdx, ok := obMeta.(fakeResResult) | |
[ 829] if !ok { | |
[ 830] t.Fatalf("%s: obMeta not of correct type: %v", t.Name(), obMeta) | |
[ 831] } | |
[ 832] scRes = fmt.Sprintf("%s.%s[%d]", ctPrefix, scPrefix, obIdx) | |
[ 833] } | |
[ 834] | |
[ 835] if !found { | |
[ 836] return nil, "", fmt.Errorf("prefix or object not found") | |
[ 837] } | |
[ 838] return tp, scRes, nil | |
[ 839] }() | |
[ 840] | |
[ 841] if !testutils.IsError(err, tc.err) { | |
[ 842] t.Fatalf("%s: expected %s, but found %v", t.Name(), tc.err, err) | |
[ 843] } | |
[ 844] if tc.err != "" { | |
[ 845] return | |
[ 846] } | |
[ 847] if out := tp.String(); tc.out != out { | |
[ 848] t.Errorf("%s: expected %s, but found %s", t.Name(), tc.out, out) | |
[ 849] } | |
[ 850] switch tpv := tp.(type) { | |
[ 851] case *tree.AllTablesSelector: | |
[ 852] tpv.TableNamePrefix.ExplicitCatalog = true | |
[ 853] tpv.TableNamePrefix.ExplicitSchema = true | |
[ 854] case *tree.TableName: | |
[ 855] tpv.TableNamePrefix.ExplicitCatalog = true | |
[ 856] tpv.TableNamePrefix.ExplicitSchema = true | |
[ 857] } | |
[ 858] if out := tp.String(); tc.expanded != out { | |
[ 859] t.Errorf("%s: expected full %s, but found %s", t.Name(), tc.expanded, out) | |
[ 860] } | |
[ 861] if tc.scName != sc { | |
[ 862] t.Errorf("%s: expected schema %s, but found %s", t.Name(), tc.scName, sc) | |
[ 863] } | |
[ 864] }) | |
[ 865] } | |
[ 866] } | |
[INFO][00:17:47] Applied 'ShowPatchAction' on 'pkg/sql/sem/tree/name_resolution_test.go' from 'GofmtBear'. | |
[WARNING][00:17:47] GoVetBear: This result has no patch attached. | |
pkg/sql/sem/tree/name_resolution_test.go | |
[ 13] //·permissions·and·limitations·under·the·License. | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! expected type, found '=' | |
[WARNING][00:17:51] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:51] GoVetBear: This result has no patch attached. | |
pkg/sql/session.go | |
[1144] » » panic(fmt.Sprintf( | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg state for printf verb %s of wrong type: sql.TxnStateEnum | |
pkg/sql/session.go | |
[1212] » » panic(fmt.Sprintf( | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg ts.State() for printf verb %s of wrong type: sql.TxnStateEnum | |
[WARNING][00:17:52] GoVetBear: This result has no patch attached. | |
[WARNING][00:17:52] GoVetBear: This result has no patch attached. | |
pkg/sql/distsqlrun/routers_test.go | |
[ 325] » » » » row0·=·sqlbase.EncDatumRow{sqlbase.DatumToEncDatum(colTypes[0],·d)} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.EncDatumRow composite literal uses unkeyed fields | |
pkg/sql/distsqlrun/routers_test.go | |
[ 327] » » » » row1·=·sqlbase.EncDatumRow{sqlbase.DatumToEncDatum(colTypes[0],·d)} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.EncDatumRow composite literal uses unkeyed fields | |
**** GofmtBear [Section <empty> | Severity NORMAL] **** | |
! ! Formatting can be improved. | |
[----] /home/palash25/Dev/cockroach/pkg/sql/resolver.go | |
[++++] /home/palash25/Dev/cockroach/pkg/sql/resolver.go | |
[ 1] // Copyright 2018 The Cockroach Authors. | |
[ 2] // | |
[ 3] // Licensed under the Apache License, Version 2.0 (the "License"); | |
[ 4] // you may not use this file except in compliance with the License. | |
[ 5] // You may obtain a copy of the License at | |
[ 6] // | |
[ 7] // http://www.apache.org/licenses/LICENSE-2.0 | |
[ 8] // | |
[ 9] // Unless required by applicable law or agreed to in writing, software | |
[ 10] // distributed under the License is distributed on an "AS IS" BASIS, | |
[ 11] // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
[ 12] // implied. See the License for the specific language governing | |
[ 13] // permissions and limitations under the License. | |
[ 14] | |
[ 15] package sql | |
[ 16] | |
[ 17] import ( | |
[ 18] "context" | |
[ 19] "fmt" | |
[ 20] | |
[ 21] "github.com/cockroachdb/cockroach/pkg/internal/client" | |
[ 22] "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" | |
[ 23] "github.com/cockroachdb/cockroach/pkg/sql/privilege" | |
[ 24] "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" | |
[ 25] "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" | |
[ 26] "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" | |
[ 27] ) | |
[ 28] | |
[ 29] // SchemaResolver abstracts the interfaces needed from the logical | |
[ 30] // planner to perform name resolution below. | |
[ 31] // | |
[ 32] // We use an interface instead of passing *planner directly to make | |
[ 33] // the resolution methods able to work even when we evolve the code to | |
[ 34] // use a different plan builder. | |
[ 35] // TODO(rytaft,andyk): study and reuse this. | |
[ 36] type SchemaResolver interface { | |
[ 37] tree.TableNameExistingResolver | |
[ 38] tree.TableNameTargetResolver | |
[ 39] | |
[ 40] Txn() *client.Txn | |
[ 41] LogicalSchemaAccessor() SchemaAccessor | |
[ 42] CurrentDatabase() string | |
[ 43] CurrentSearchPath() sessiondata.SearchPath | |
[ 44] CommonLookupFlags(ctx context.Context, required bool) CommonLookupFlags | |
[ 45] ObjectLookupFlags(ctx context.Context, required bool) ObjectLookupFlags | |
[ 46] } | |
[ 47] | |
[ 48] var _ SchemaResolver = &planner{} | |
[ 49] | |
[ 50] // ResolveDatabase looks up a database name. | |
[ 51] func ResolveDatabase( | |
[ 52] ctx context.Context, sc SchemaResolver, dbName string, required bool, | |
[ 53] ) (res *DatabaseDescriptor, err error) { | |
[ 54] return sc.LogicalSchemaAccessor().GetDatabaseDesc(dbName, | |
[ 55] sc.CommonLookupFlags(ctx, required)) | |
[ 56] } | |
[ 57] | |
[ 58] // GetObjectNames retrieves the names of all objects in the target database/schema. | |
[ 59] func GetObjectNames( | |
[ 60] ctx context.Context, | |
[ 61] sc SchemaResolver, | |
[ 62] dbDesc *DatabaseDescriptor, | |
[ 63] scName string, | |
[ 64] explicitPrefix bool, | |
[ 65] ) (res TableNames, err error) { | |
[ 66] return sc.LogicalSchemaAccessor().GetObjectNames(dbDesc, scName, | |
[ 67] DatabaseListFlags{ | |
[ 68] CommonLookupFlags: sc.CommonLookupFlags(ctx, true /*required*/), | |
[ 69] explicitPrefix: explicitPrefix, | |
[ 70] }) | |
[ 71] } | |
[ 72] | |
[ 73] // ResolveExistingObject looks up an existing object. | |
[ 74] // If required is true, an error is returned if the object does not exist. | |
[ 75] // Optionally, if a desired descriptor type is specified, that type is checked. | |
[ 76] // | |
[ 77] // The object name is modified in-place with the result of the name | |
[ 78] // resolution, if successful. It is not modified in case of error or | |
[ 79] // if no object is found. | |
[ 80] func ResolveExistingObject( | |
[ 81] ctx context.Context, sc SchemaResolver, tn *ObjectName, required bool, requiredType requiredType, | |
[ 82] ) (res *ObjectDescriptor, err error) { | |
[ 83] found, descI, err := tn.ResolveExisting(ctx, sc, sc.CurrentDatabase(), sc.CurrentSearchPath()) | |
[ 84] if err != nil { | |
[ 85] return nil, err | |
[ 86] } | |
[ 87] if !found { | |
[ 88] if required { | |
[ 89] return nil, sqlbase.NewUndefinedRelationError(tn) | |
[ 90] } | |
[ 91] return nil, nil | |
[ 92] } | |
[ 93] desc := descI.(*ObjectDescriptor) | |
[ 94] goodType := true | |
[ 95] switch requiredType { | |
[ 96] case requireTableDesc: | |
[ 97] goodType = desc.IsTable() | |
[ 98] case requireViewDesc: | |
[ 99] goodType = desc.IsView() | |
[ 100] case requireTableOrViewDesc: | |
[ 101] goodType = desc.IsTable() || desc.IsView() | |
[ 102] case requireSequenceDesc: | |
[ 103] goodType = desc.IsSequence() | |
[ 104] } | |
[ 105] if !goodType { | |
[ 106] return nil, sqlbase.NewWrongObjectTypeError(tn, requiredTypeNames[requiredType]) | |
[ 107] } | |
[ 108] return desc, nil | |
[ 109] } | |
[ 110] | |
[ 111] // runWithOptions sets the provided resolution flags for the | |
[ 112] // duration of the call of the passed argument fn. | |
[ 113] // | |
[ 114] // This is meant to be used like this (for example): | |
[ 115] // | |
[ 116] // var someVar T | |
[ 117] // var err error | |
[ 118] // p.runWithOptions(resolveFlags{allowAdding: true}, func() { | |
[ 119] // someVar, err = ResolveExistingObject(ctx, p, ...) | |
[ 120] // }) | |
[ 121] // if err != nil { ... } | |
[ 122] // use(someVar) | |
[ 123] func (p *planner) runWithOptions(flags resolveFlags, fn func()) { | |
[ 124] if flags.allowAdding { | |
[ 125] defer func(prev bool) { p.revealNewDescriptors = prev }(p.revealNewDescriptors) | |
[ 126] p.revealNewDescriptors = true | |
[ 127] } | |
[ 128] if flags.skipCache { | |
[ 129] defer func(prev bool) { p.avoidCachedDescriptors = prev }(p.avoidCachedDescriptors) | |
[ 130] p.avoidCachedDescriptors = true | |
[ 131] } | |
[ 132] fn() | |
[ 133] } | |
[ 134] | |
[ 135] type resolveFlags struct { | |
[ 136] allowAdding bool | |
[ 137] skipCache bool | |
[ 138] } | |
[ 139] | |
[ 140] // ResolveTargetObject determines a valid target path for an object | |
[ 141] // that may not exist yet. It returns the descriptor for the database | |
[ 142] // where the target object lives. | |
[ 143] // | |
[ 144] // The object name is modified in-place with the result of the name | |
[ 145] // resolution. | |
[ 146] func ResolveTargetObject( | |
[ 147] ctx context.Context, sc SchemaResolver, tn *ObjectName, | |
[ 148] ) (res *DatabaseDescriptor, err error) { | |
[ 149] found, descI, err := tn.ResolveTarget(ctx, sc, sc.CurrentDatabase(), sc.CurrentSearchPath()) | |
[ 150] if err != nil { | |
[ 151] return nil, err | |
[ 152] } | |
[ 153] if !found { | |
[ 154] return nil, pgerror.NewErrorf(pgerror.CodeInvalidNameError, | |
[ 155] "invalid target name: %q", tree.ErrString(tn)) | |
[ 156] } | |
[ 157] if tn.Schema() != tree.PublicSchema { | |
[ 158] return nil, pgerror.NewErrorf(pgerror.CodeInvalidNameError, | |
[ 159] "schema cannot be modified: %q", tree.ErrString(&tn.TableNamePrefix)) | |
[ 160] } | |
[ 161] return descI.(*DatabaseDescriptor), nil | |
[ 162] } | |
[ 163] | |
[ 164] // requiredType can be passed to the ResolveExistingObject function to | |
[ 165] // require the returned descriptor to be of a specific type. | |
[ 166] type requiredType int | |
[ 167] | |
[ 168] const ( | |
[ 169] anyDescType requiredType = iota | |
[ 170] requireTableDesc | |
[ 171] requireViewDesc | |
[ 172] requireTableOrViewDesc | |
[ 173] requireSequenceDesc | |
[ 174] ) | |
[ 175] | |
[ 176] var requiredTypeNames = [...]string{ | |
[ 177] requireTableDesc: "table", | |
[ 178] requireViewDesc: "view", | |
[ 179] requireTableOrViewDesc: "table or view", | |
[ 180] requireSequenceDesc: "sequence", | |
[ 181] } | |
[ 182] | |
[ 183] // LookupSchema implements the tree.TableNameTargetResolver interface. | |
[ 184] func (p *planner) LookupSchema( | |
[ 185] ctx context.Context, dbName, scName string, | |
[ 186] ) (found bool, scMeta tree.SchemaMeta, err error) { | |
[ 187] sc := p.LogicalSchemaAccessor() | |
[ 188] dbDesc, err := sc.GetDatabaseDesc(dbName, p.CommonLookupFlags(ctx, false /*required*/)) | |
[ 189] if err != nil || dbDesc == nil { | |
[ 190] return false, nil, err | |
[ 191] } | |
[ 192] return sc.IsValidSchema(dbDesc, scName), dbDesc, nil | |
[ 193] } | |
[ 194] | |
[ 195] // LookupObject implements the tree.TableNameExistingResolver interface. | |
[ 196] func (p *planner) LookupObject( | |
[ 197] ctx context.Context, dbName, scName, tbName string, | |
[ 198] ) (found bool, objMeta tree.NameResolutionResult, err error) { | |
[ 199] sc := p.LogicalSchemaAccessor() | |
[ 200] // TODO(knz): elide this allocation of TableName. | |
[ 201] tn := tree.MakeTableNameWithSchema(tree.Name(dbName), tree.Name(scName), tree.Name(tbName)) | |
[ 202] objDesc, _, err := sc.GetObjectDesc(&tn, p.ObjectLookupFlags(ctx, false /*required*/)) | |
[ 203] return objDesc != nil, objDesc, err | |
[ 204] } | |
[ 205] | |
[ 206] func (p *planner) CommonLookupFlags(ctx context.Context, required bool) CommonLookupFlags { | |
[ 207] return CommonLookupFlags{ | |
[ 208] ctx: ctx, | |
[ 209] txn: p.txn, | |
[ 210] required: required, | |
[ 211] avoidCached: p.avoidCachedDescriptors, | |
[ 212] } | |
[ 213] } | |
[ 214] | |
[ 215] func (p *planner) ObjectLookupFlags(ctx context.Context, required bool) ObjectLookupFlags { | |
[ 216] return ObjectLookupFlags{ | |
[ 217] CommonLookupFlags: p.CommonLookupFlags(ctx, required), | |
[ 218] allowAdding: p.revealNewDescriptors, | |
[ 219] } | |
[ 220] } | |
[ 221] | |
[ 222] // getDescriptorsFromTargetList fetches the descriptors for the targets. | |
[ 223] func getDescriptorsFromTargetList( | |
[ 224] ctx context.Context, sc SchemaResolver, targets tree.TargetList, | |
[ 225] ) ([]sqlbase.DescriptorProto, error) { | |
[ 226] if targets.Databases != nil { | |
[ 227] if len(targets.Databases) == 0 { | |
[ 228] return nil, errNoDatabase | |
[ 229] } | |
[ 230] descs := make([]sqlbase.DescriptorProto, 0, len(targets.Databases)) | |
[ 231] for _, database := range targets.Databases { | |
[ 232] descriptor, err := ResolveDatabase(ctx, sc, string(database), true /*required*/) | |
[ 233] if err != nil { | |
[ 234] return nil, err | |
[ 235] } | |
[ 236] descs = append(descs, descriptor) | |
[ 237] } | |
[ 238] if len(descs) == 0 { | |
[ 239] return nil, errNoMatch | |
[ 240] } | |
[ 241] return descs, nil | |
[ 242] } | |
[ 243] | |
[ 244] if len(targets.Tables) == 0 { | |
[ 245] return nil, errNoTable | |
[ 246] } | |
[ 247] descs := make([]sqlbase.DescriptorProto, 0, len(targets.Tables)) | |
[ 248] for _, tableTarget := range targets.Tables { | |
[ 249] tableGlob, err := tableTarget.NormalizeTablePattern() | |
[ 250] if err != nil { | |
[ 251] return nil, err | |
[ 252] } | |
[ 253] tableNames, err := expandTableGlob(ctx, sc, tableGlob) | |
[ 254] if err != nil { | |
[ 255] return nil, err | |
[ 256] } | |
[ 257] for i := range tableNames { | |
[ 258] descriptor, _, err := sc.LogicalSchemaAccessor().GetObjectDesc(&tableNames[i], | |
[ 259] sc.ObjectLookupFlags(ctx, true /*required*/)) | |
[ 260] if err != nil { | |
[ 261] return nil, err | |
[ 262] } | |
[ 263] descs = append(descs, descriptor) | |
[ 264] } | |
[ 265] } | |
[ 266] if len(descs) == 0 { | |
[ 267] return nil, errNoMatch | |
[ 268] } | |
[ 269] return descs, nil | |
[ 270] } | |
[ 271] | |
[ 272] // getQualifiedTableName returns the database-qualified name of the table | |
[ 273] // or view represented by the provided descriptor. It is a sort of | |
[ 274] // reverse of the Resolve() functions. | |
[ 275] func (p *planner) getQualifiedTableName( | |
[ 276] ctx context.Context, desc *sqlbase.TableDescriptor, | |
[ 277] ) (string, error) { | |
[ 278] dbDesc, err := sqlbase.GetDatabaseDescFromID(ctx, p.txn, desc.ParentID) | |
[ 279] if err != nil { | |
[ 280] return "", err | |
[ 281] } | |
[ 282] tbName := tree.MakeTableName(tree.Name(dbDesc.Name), tree.Name(desc.Name)) | |
[ 283] return tbName.String(), nil | |
[ 284] } | |
[ 285] | |
[ 286] // findTableContainingIndex returns the name of the table containing an | |
[ 287] // index of the given name and its descriptor. | |
[ 288] // This is used by expandIndexName(). | |
[ 289] // | |
[ 290] // An error is returned if the index name is ambiguous (i.e. exists in | |
[ 291] // multiple tables). If no table is found and requireTable is true, an | |
[ 292] // error will be returned, otherwise the TableName and descriptor | |
[ 293] // returned will be nil. | |
[ 294] func findTableContainingIndex( | |
[ 295] sc SchemaAccessor, dbName string, idxName tree.UnrestrictedName, lookupFlags CommonLookupFlags, | |
[ 296] ) (result *tree.TableName, desc *sqlbase.TableDescriptor, err error) { | |
[ 297] dbDesc, err := sc.GetDatabaseDesc(dbName, lookupFlags) | |
[ 298] if dbDesc == nil || err != nil { | |
[ 299] return nil, nil, err | |
[ 300] } | |
[ 301] | |
[ 302] tns, err := sc.GetObjectNames(dbDesc, tree.PublicSchema, | |
[ 303] DatabaseListFlags{CommonLookupFlags: lookupFlags, explicitPrefix: true}) | |
[ 304] if err != nil { | |
[ 305] return nil, nil, err | |
[ 306] } | |
[ 307] | |
[ 308] result = nil | |
[ 309] tblLookupFlags := ObjectLookupFlags{CommonLookupFlags: lookupFlags} | |
[ 310] tblLookupFlags.required = false | |
[ 311] for i := range tns { | |
[ 312] tn := &tns[i] | |
[ 313] tableDesc, _, err := sc.GetObjectDesc(tn, tblLookupFlags) | |
[ 314] if err != nil { | |
[ 315] return nil, nil, err | |
[ 316] } | |
[ 317] if tableDesc == nil || !tableDesc.IsTable() { | |
[ 318] continue | |
[ 319] } | |
[ 320] | |
[ 321] _, dropped, err := tableDesc.FindIndexByName(string(idxName)) | |
[ 322] if err != nil || dropped { | |
[ 323] // err is nil if the index does not exist on the table. | |
[ 324] continue | |
[ 325] } | |
[ 326] if result != nil { | |
[ 327] return nil, nil, pgerror.NewErrorf(pgerror.CodeAmbiguousParameterError, | |
[ 328] "index name %q is ambiguous (found in %s and %s)", | |
[ 329] idxName, tn.String(), result.String()) | |
[ 330] } | |
[ 331] result = tn | |
[ 332] desc = tableDesc | |
[ 333] } | |
[ 334] if result == nil && lookupFlags.required { | |
[ 335] return nil, nil, pgerror.NewErrorf(pgerror.CodeUndefinedObjectError, | |
[ 336] "index %q does not exist", idxName) | |
[ 337] } | |
[ 338] return result, desc, nil | |
[ 339] } | |
[ 340] | |
[ 341] // expandIndexName ensures that the index name is qualified with a table | |
[ 342] // name, and searches the table name if not yet specified. | |
[ 343] // | |
[ 344] // It returns the TableName of the underlying table for convenience. | |
[ 345] // If no table is found and requireTable is true an error will be | |
[ 346] // returned, otherwise the TableName returned will be nil. | |
[ 347] // | |
[ 348] // It *may* return the descriptor of the underlying table, depending | |
[ 349] // on the lookup path. This can be used in the caller to avoid a 2nd | |
[ 350] // lookup. | |
[ 351] func expandIndexName( | |
[ 352] ctx context.Context, sc SchemaResolver, index *tree.TableNameWithIndex, requireTable bool, | |
[ 353] ) (tn *tree.TableName, desc *sqlbase.TableDescriptor, err error) { | |
[ 354] tn, err = index.Table.Normalize() | |
[ 355] if err != nil { | |
[ 356] return nil, nil, err | |
[ 357] } | |
[ 358] | |
[ 359] if !index.SearchTable { | |
[ 360] // The index and its table prefix must exist already. Resolve the table. | |
[ 361] desc, err = ResolveExistingObject(ctx, sc, tn, requireTable, requireTableDesc) | |
[ 362] if err != nil { | |
[ 363] return nil, nil, err | |
[ 364] } | |
[ 365] } else { | |
[ 366] // On the first call to expandIndexName(), index.SearchTable is | |
[ 367] // true, index.Index is empty and tn.Table() is the index | |
[ 368] // name. Once the table name is resolved for the index below, | |
[ 369] // index.Table references a new table name (not the index), so a | |
[ 370] // subsequent call to expandIndexName() will generate tn using the | |
[ 371] // new value of index.Table, which is a table name. | |
[ 372] | |
[ 373] // Just an assertion: if we got there, there cannot be a path prefix | |
[ 374] // in tn or a value in index.Index yet. | |
[ 375] if tn.ExplicitSchema || tn.ExplicitCatalog || index.Index != "" { | |
[ 376] return nil, nil, pgerror.NewErrorf(pgerror.CodeInternalError, | |
[ 377] "programmer error: not-searched index name found already qualified: %s@%s", tn, index.Index) | |
[ 378] } | |
[ 379] | |
[ 380] curDb := sc.CurrentDatabase() | |
[ 381] if curDb == "" { | |
[ 382] return nil, nil, pgerror.NewErrorf(pgerror.CodeUndefinedObjectError, | |
[ 383] "no database specified: %q", tree.ErrString(index)) | |
[ 384] } | |
[ 385] | |
[ 386] index.Index = tree.UnrestrictedName(tn.TableName) | |
[ 387] lookupFlags := sc.CommonLookupFlags(ctx, requireTable) | |
[ 388] tn, desc, err = findTableContainingIndex( | |
[ 389] sc.LogicalSchemaAccessor(), curDb, index.Index, lookupFlags) | |
[ 390] if err != nil { | |
[ 391] return nil, nil, err | |
[ 392] } else if tn == nil { | |
[ 393] // NB: tn is nil here if and only if requireTable is | |
[ 394] // false, otherwise err would be non-nil. | |
[ 395] return nil, nil, nil | |
[ 396] } | |
[ 397] // Memoize the resolved table name in case expandIndexName() is called again. | |
[ 398] index.Table.TableNameReference = tn | |
[ 399] } | |
[ 400] return tn, desc, nil | |
[ 401] } | |
[ 402] | |
[ 403] // getTableAndIndex returns the table and index descriptors for a table | |
[ 404] // (primary index) or table-with-index. Only one of table and tableWithIndex can | |
[ 405] // be set. This is useful for statements that have both table and index | |
[ 406] // variants (like `ALTER TABLE/INDEX ... SPLIT AT ...`). | |
[ 407] // It can return indexes that are being rolled out. | |
[ 408] func (p *planner) getTableAndIndex( | |
[ 409] ctx context.Context, | |
[ 410] table *tree.NormalizableTableName, | |
[ 411] tableWithIndex *tree.TableNameWithIndex, | |
[ 412] privilege privilege.Kind, | |
[ 413] ) (*sqlbase.TableDescriptor, *sqlbase.IndexDescriptor, error) { | |
[ 414] var tn *tree.TableName | |
[ 415] var tableDesc *sqlbase.TableDescriptor | |
[ 416] var err error | |
[ 417] | |
[ 418] // DDL statements avoid the cache to avoid leases, and can view non-public descriptors. | |
[ 419] // TODO(vivek): check if the cache can be used. | |
[ 420] p.runWithOptions(resolveFlags{allowAdding: true, skipCache: true}, func() { | |
[ 421] if tableWithIndex == nil { | |
[ 422] // Variant: ALTER TABLE | |
[ 423] tn, err = table.Normalize() | |
[ 424] if err != nil { | |
[ 425] return | |
[ 426] } | |
[ 427] tableDesc, err = ResolveExistingObject(ctx, p, tn, true /*required*/, requireTableDesc) | |
[ 428] } else { | |
[ 429] // Variant: ALTER INDEX | |
[ 430] tn, tableDesc, err = expandIndexName(ctx, p, tableWithIndex, true /* requireTable */) | |
[ 431] } | |
[ 432] }) | |
[ 433] if err != nil { | |
[ 434] return nil, nil, err | |
[ 435] } | |
[ 436] | |
[ 437] if err := p.CheckPrivilege(ctx, tableDesc, privilege); err != nil { | |
[ 438] return nil, nil, err | |
[ 439] } | |
[ 440] | |
[ 441] // Determine which index to use. | |
[ 442] var index sqlbase.IndexDescriptor | |
[ 443] if tableWithIndex == nil { | |
[ 444] index = tableDesc.PrimaryIndex | |
[ 445] } else { | |
[ 446] idx, dropped, err := tableDesc.FindIndexByName(string(tableWithIndex.Index)) | |
[ 447] if err != nil { | |
[ 448] return nil, nil, err | |
[ 449] } | |
[ 450] if dropped { | |
[ 451] return nil, nil, fmt.Errorf("index %q being dropped", tableWithIndex.Index) | |
[ 452] } | |
[ 453] index = idx | |
[ 454] } | |
[ 455] return tableDesc, &index, nil | |
[ 456] } | |
[ 457] | |
[ 458] // expandTableGlob expands pattern into a list of tables represented | |
[ 459] // as a tree.TableNames. | |
[ 460] func expandTableGlob( | |
[ 461] ctx context.Context, sc SchemaResolver, pattern tree.TablePattern, | |
[ 462] ) (tree.TableNames, error) { | |
[ 463] if t, ok := pattern.(*tree.TableName); ok { | |
[ 464] _, err := ResolveExistingObject(ctx, sc, t, true /*required*/, anyDescType) | |
[ 465] if err != nil { | |
[ 466] return nil, err | |
[ 467] } | |
[ 468] return tree.TableNames{*t}, nil | |
[ 469] } | |
[ 470] | |
[ 471] glob := pattern.(*tree.AllTablesSelector) | |
[ 472] found, descI, err := glob.TableNamePrefix.Resolve( | |
[ 473] ctx, sc, sc.CurrentDatabase(), sc.CurrentSearchPath()) | |
[ 474] if err != nil { | |
[ 475] return nil, err | |
[ 476] } | |
[ 477] if !found { | |
[ 478] return nil, sqlbase.NewInvalidWildcardError(tree.ErrString(glob)) | |
[ 479] } | |
[ 480] | |
[ 481] return GetObjectNames(ctx, sc, descI.(*DatabaseDescriptor), glob.Schema(), glob.ExplicitSchema) | |
[ 482] } | |
[ 483] | |
[ 484] // fkSelfResolver is a SchemaResolver that inserts itself between a | |
[ 485] // user of name resolution and another SchemaResolver, and will answer | |
[ 486] // lookups of the new table being created. This is needed in the case | |
[ 487] // of CREATE TABLE with a foreign key self-reference: the target of | |
[ 488] // the FK definition is a table that does not exist yet. | |
[ 489] type fkSelfResolver struct { | |
[ 490] SchemaResolver | |
[ 491] newTableName *tree.TableName | |
[ 492] newTableDesc *sqlbase.TableDescriptor | |
[ 493] } | |
[ 494] | |
[ 495] var _ SchemaResolver = &fkSelfResolver{} | |
[ 496] | |
[ 497] // LookupObject implements the tree.TableNameExistingResolver interface. | |
[ 498] func (r *fkSelfResolver) LookupObject( | |
[ 499] ctx context.Context, dbName, scName, tbName string, | |
[ 500] ) (found bool, objMeta tree.NameResolutionResult, err error) { | |
[ 501] if dbName == r.newTableName.Catalog() && | |
[ 502] scName == r.newTableName.Schema() && | |
[ 503] tbName == r.newTableName.Table() { | |
[ 504] return true, r.newTableDesc, nil | |
[ 505] } | |
[ 506] return r.SchemaResolver.LookupObject(ctx, dbName, scName, tbName) | |
[ 507] } | |
[ 508] | |
[ 509] // internalLookupCtx can be used in contexts where all descriptors | |
[ 510] // have been recently read, to accelerate the lookup of | |
[ 511] // inter-descriptor relationships. | |
[ 512] // | |
[ 513] // This is used mainly in the generators for virtual tables, | |
[ 514] // aliased as tableLookupFn below. | |
[ 515] // | |
[ 516] // It only reveals physical descriptors (not virtual descriptors). | |
[ 517] type internalLookupCtx struct { | |
[ 518] dbNames map[sqlbase.ID]string | |
[ 519] dbIDs []sqlbase.ID | |
[ 520] dbDescs map[sqlbase.ID]*DatabaseDescriptor | |
[ 521] tbDescs map[sqlbase.ID]*TableDescriptor | |
[ 522] tbIDs []sqlbase.ID | |
[ 523] } | |
[ 524] | |
[ 525] // tableLookupFn can be used to retrieve a table descriptor and its corresponding | |
[ 526] // database descriptor using the table's ID. | |
[ 527] type tableLookupFn = *internalLookupCtx | |
[ 528] | |
[ 529] func newInternalLookupCtx( | |
[ 530] descs []sqlbase.DescriptorProto, prefix *DatabaseDescriptor, | |
[ 531] ) *internalLookupCtx { | |
[ 532] dbNames := make(map[sqlbase.ID]string) | |
[ 533] dbDescs := make(map[sqlbase.ID]*DatabaseDescriptor) | |
[ 534] tbDescs := make(map[sqlbase.ID]*TableDescriptor) | |
[ 535] var tbIDs, dbIDs []sqlbase.ID | |
[ 536] // Record database descriptors for name lookups. | |
[ 537] for _, desc := range descs { | |
[ 538] switch d := desc.(type) { | |
[ 539] case *sqlbase.DatabaseDescriptor: | |
[ 540] dbNames[d.ID] = d.Name | |
[ 541] dbDescs[d.ID] = d | |
[ 542] if prefix == nil || prefix.ID == d.ID { | |
[ 543] dbIDs = append(dbIDs, d.ID) | |
[ 544] } | |
[ 545] case *sqlbase.TableDescriptor: | |
[ 546] tbDescs[d.ID] = d | |
[ 547] if prefix == nil || prefix.ID == d.ParentID { | |
[ 548] // Only make the table visible for iteration if the prefix was included. | |
[ 549] tbIDs = append(tbIDs, d.ID) | |
[ 550] } | |
[ 551] } | |
[ 552] } | |
[ 553] return &internalLookupCtx{ | |
[ 554] dbNames: dbNames, | |
[ 555] dbDescs: dbDescs, | |
[ 556] tbDescs: tbDescs, | |
[ 557] tbIDs: tbIDs, | |
[ 558] dbIDs: dbIDs, | |
[ 559] } | |
[ 560] } | |
[ 561] | |
[ 562] func (l *internalLookupCtx) getDatabaseByID(id sqlbase.ID) (*DatabaseDescriptor, error) { | |
[ 563] db, ok := l.dbDescs[id] | |
[ 564] if !ok { | |
[ 565] return nil, sqlbase.NewUndefinedDatabaseError(fmt.Sprintf("[%d]", id)) | |
[ 566] } | |
[ 567] return db, nil | |
[ 568] } | |
[ 569] | |
[ 570] func (l *internalLookupCtx) getTableByID(id sqlbase.ID) (*TableDescriptor, error) { | |
[ 571] tb, ok := l.tbDescs[id] | |
[ 572] if !ok { | |
[ 573] return nil, sqlbase.NewUndefinedRelationError( | |
[ 574] tree.NewUnqualifiedTableName(tree.Name(fmt.Sprintf("[%d]", id)))) | |
[ 575] } | |
[ 576] return tb, nil | |
[ 577] } | |
[ 578] | |
[ 579] func (l *internalLookupCtx) getParentName(table *TableDescriptor) string { | |
[ 580] parentName := l.dbNames[table.GetParentID()] | |
[ 581] if parentName == "" { | |
[ 582] // The parent database was deleted. This is possible e.g. when | |
[ 583] // a database is dropped with CASCADE, and someone queries | |
[ 584] // this virtual table before the dropped table descriptors are | |
[ 585] // effectively deleted. | |
[ 586] parentName = fmt.Sprintf("[%d]", table.GetParentID()) | |
[ 587] } | |
[ 588] return parentName | |
[ 589] } | |
[INFO][00:17:52] Applied 'ShowPatchAction' on 'pkg/sql/resolver.go' from 'GofmtBear'. | |
[WARNING][00:17:52] GoVetBear: This result has no patch attached. | |
pkg/sql/resolver.go | |
[ 20] | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! expected type, found '=' (and 4 more errors) | |
**** GofmtBear [Section <empty> | Severity NORMAL] **** | |
! ! Formatting can be improved. | |
[----] /home/palash25/Dev/cockroach/pkg/sql/plan.go | |
[++++] /home/palash25/Dev/cockroach/pkg/sql/plan.go | |
[ 1] // Copyright 2015 The Cockroach Authors. | |
[ 2] // | |
[ 3] // Licensed under the Apache License, Version 2.0 (the "License"); | |
[ 4] // you may not use this file except in compliance with the License. | |
[ 5] // You may obtain a copy of the License at | |
[ 6] // | |
[ 7] // http://www.apache.org/licenses/LICENSE-2.0 | |
[ 8] // | |
[ 9] // Unless required by applicable law or agreed to in writing, software | |
[ 10] // distributed under the License is distributed on an "AS IS" BASIS, | |
[ 11] // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
[ 12] // implied. See the License for the specific language governing | |
[ 13] // permissions and limitations under the License. | |
[ 14] | |
[ 15] package sql | |
[ 16] | |
[ 17] import ( | |
[ 18] "context" | |
[ 19] | |
[ 20] "github.com/pkg/errors" | |
[ 21] | |
[ 22] "github.com/cockroachdb/cockroach/pkg/roachpb" | |
[ 23] "github.com/cockroachdb/cockroach/pkg/sql/opt/exec/execbuilder" | |
[ 24] "github.com/cockroachdb/cockroach/pkg/sql/opt/optbuilder" | |
[ 25] "github.com/cockroachdb/cockroach/pkg/sql/opt/xform" | |
[ 26] "github.com/cockroachdb/cockroach/pkg/sql/parser" | |
[ 27] "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" | |
[ 28] "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" | |
[ 29] "github.com/cockroachdb/cockroach/pkg/sql/sem/types" | |
[ 30] "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" | |
[ 31] "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" | |
[ 32] "github.com/cockroachdb/cockroach/pkg/util/log" | |
[ 33] "github.com/cockroachdb/cockroach/pkg/util/tracing" | |
[ 34] ) | |
[ 35] | |
[ 36] type planMaker interface { | |
[ 37] // newPlan starts preparing the query plan for a single SQL | |
[ 38] // statement. | |
[ 39] // | |
[ 40] // It performs as many early checks as possible on the structure of | |
[ 41] // the SQL statement, including verifying permissions and type | |
[ 42] // checking. The returned plan object is not ready to execute; the | |
[ 43] // optimizePlan() method must be called first. See makePlan() | |
[ 44] // below. | |
[ 45] // | |
[ 46] // This method should not be used directly; instead prefer makePlan() | |
[ 47] // or prepare() below. | |
[ 48] newPlan( | |
[ 49] ctx context.Context, stmt tree.Statement, desiredTypes []types.T, | |
[ 50] ) (planNode, error) | |
[ 51] | |
[ 52] // makePlan prepares the query plan for a single SQL statement. it | |
[ 53] // calls newPlan() then optimizePlan() on the result. | |
[ 54] // The logical plan is stored in the planner's curPlan field. | |
[ 55] // | |
[ 56] // Execution must start by calling curPlan.start() first and then | |
[ 57] // iterating using curPlan.plan.Next() and curPlan.plan.Values() in | |
[ 58] // order to retrieve matching rows. Finally, the plan must be closed | |
[ 59] // with curPlan.close(). | |
[ 60] makePlan(ctx context.Context, stmt Statement) error | |
[ 61] | |
[ 62] // prepare does the same checks as makePlan but skips building some | |
[ 63] // data structures necessary for execution, based on the assumption | |
[ 64] // that the plan will never be run. A planNode built with prepare() | |
[ 65] // will do just enough work to check the structural validity of the | |
[ 66] // SQL statement and determine types for placeholders. However it is | |
[ 67] // not appropriate to call optimizePlan(), Next() or Values() on a plan | |
[ 68] // object created with prepare(). | |
[ 69] // The plan should still be closed with p.curPlan.close() though. | |
[ 70] prepare(ctx context.Context, stmt tree.Statement) error | |
[ 71] } | |
[ 72] | |
[ 73] var _ planMaker = &planner{} | |
[ 74] | |
[ 75] // runParams is a struct containing all parameters passed to planNode.Next() and | |
[ 76] // planNode.Start(). | |
[ 77] type runParams struct { | |
[ 78] // context.Context for this method call. | |
[ 79] ctx context.Context | |
[ 80] | |
[ 81] // extendedEvalCtx groups fields useful for this execution. | |
[ 82] // Used during local execution and distsql physical planning. | |
[ 83] extendedEvalCtx *extendedEvalContext | |
[ 84] | |
[ 85] // planner associated with this execution. Only used during local | |
[ 86] // execution. | |
[ 87] p *planner | |
[ 88] } | |
[ 89] | |
[ 90] // EvalContext() gives convenient access to the runParam's EvalContext(). | |
[ 91] func (r *runParams) EvalContext() *tree.EvalContext { | |
[ 92] return &r.extendedEvalCtx.EvalContext | |
[ 93] } | |
[ 94] | |
[ 95] // SessionData gives convenient access to the runParam's SessionData. | |
[ 96] func (r *runParams) SessionData() *sessiondata.SessionData { | |
[ 97] return r.extendedEvalCtx.SessionData | |
[ 98] } | |
[ 99] | |
[ 100] // planNode defines the interface for executing a query or portion of a query. | |
[ 101] // | |
[ 102] // The following methods apply to planNodes and contain special cases | |
[ 103] // for each type; they thus need to be extended when adding/removing | |
[ 104] // planNode instances: | |
[ 105] // - planMaker.newPlan() | |
[ 106] // - planMaker.doPrepare() | |
[ 107] // - planMaker.setNeededColumns() (needed_columns.go) | |
[ 108] // - planMaker.expandPlan() (expand_plan.go) | |
[ 109] // - planVisitor.visit() (walk.go) | |
[ 110] // - planNodeNames (walk.go) | |
[ 111] // - planMaker.optimizeFilters() (filter_opt.go) | |
[ 112] // - setLimitHint() (limit_hint.go) | |
[ 113] // - collectSpans() (plan_spans.go) | |
[ 114] // - planOrdering() (plan_ordering.go) | |
[ 115] // - planColumns() (plan_columns.go) | |
[ 116] // | |
[ 117] // Also, there are optional interfaces that new nodes may want to implement: | |
[ 118] // - execStartable | |
[ 119] // - autoCommitNode | |
[ 120] // | |
[ 121] type planNode interface { | |
[ 122] // Next performs one unit of work, returning false if an error is | |
[ 123] // encountered or if there is no more work to do. For statements | |
[ 124] // that return a result set, the Values() method will return one row | |
[ 125] // of results each time that Next() returns true. | |
[ 126] // See executor.go: forEachRow() for an example. | |
[ 127] // | |
[ 128] // Available after startPlan(). It is illegal to call Next() after it returns | |
[ 129] // false. It is legal to call Next() even if the node implements | |
[ 130] // planNodeFastPath and the FastPathResults() method returns true. | |
[ 131] Next(params runParams) (bool, error) | |
[ 132] | |
[ 133] // Values returns the values at the current row. The result is only valid | |
[ 134] // until the next call to Next(). | |
[ 135] // | |
[ 136] // Available after Next(). | |
[ 137] Values() tree.Datums | |
[ 138] | |
[ 139] // Close terminates the planNode execution and releases its resources. | |
[ 140] // This method should be called if the node has been used in any way (any | |
[ 141] // methods on it have been called) after it was constructed. Note that this | |
[ 142] // doesn't imply that startPlan() has been necessarily called. | |
[ 143] Close(ctx context.Context) | |
[ 144] } | |
[ 145] | |
[ 146] // PlanNode is the exported name for planNode. Useful for CCL hooks. | |
[ 147] type PlanNode = planNode | |
[ 148] | |
[ 149] // planNodeFastPath is implemented by nodes that can perform all their | |
[ 150] // work during startPlan(), possibly affecting even multiple rows. For | |
[ 151] // example, DELETE can do this. | |
[ 152] type planNodeFastPath interface { | |
[ 153] // FastPathResults returns the affected row count and true if the | |
[ 154] // node has no result set and has already executed when startPlan() completes. | |
[ 155] // Note that Next() must still be valid even if this method returns | |
[ 156] // true, although it may have nothing left to do. | |
[ 157] FastPathResults() (int, bool) | |
[ 158] } | |
[ 159] | |
[ 160] var _ planNode = &alterIndexNode{} | |
[ 161] var _ planNode = &alterTableNode{} | |
[ 162] var _ planNode = &alterSequenceNode{} | |
[ 163] var _ planNode = &createDatabaseNode{} | |
[ 164] var _ planNode = &createIndexNode{} | |
[ 165] var _ planNode = &createTableNode{} | |
[ 166] var _ planNode = &createViewNode{} | |
[ 167] var _ planNode = &createSequenceNode{} | |
[ 168] var _ planNode = &createStatsNode{} | |
[ 169] var _ planNode = &delayedNode{} | |
[ 170] var _ planNode = &deleteNode{} | |
[ 171] var _ planNode = &distinctNode{} | |
[ 172] var _ planNode = &dropDatabaseNode{} | |
[ 173] var _ planNode = &dropIndexNode{} | |
[ 174] var _ planNode = &dropTableNode{} | |
[ 175] var _ planNode = &dropViewNode{} | |
[ 176] var _ planNode = &dropSequenceNode{} | |
[ 177] var _ planNode = &zeroNode{} | |
[ 178] var _ planNode = &unaryNode{} | |
[ 179] var _ planNode = &explainDistSQLNode{} | |
[ 180] var _ planNode = &explainPlanNode{} | |
[ 181] var _ planNode = &showTraceNode{} | |
[ 182] var _ planNode = &filterNode{} | |
[ 183] var _ planNode = &groupNode{} | |
[ 184] var _ planNode = &hookFnNode{} | |
[ 185] var _ planNode = &indexJoinNode{} | |
[ 186] var _ planNode = &insertNode{} | |
[ 187] var _ planNode = &joinNode{} | |
[ 188] var _ planNode = &limitNode{} | |
[ 189] var _ planNode = &ordinalityNode{} | |
[ 190] var _ planNode = &testingRelocateNode{} | |
[ 191] var _ planNode = &renderNode{} | |
[ 192] var _ planNode = &scanNode{} | |
[ 193] var _ planNode = &scatterNode{} | |
[ 194] var _ planNode = &showRangesNode{} | |
[ 195] var _ planNode = &showFingerprintsNode{} | |
[ 196] var _ planNode = &sortNode{} | |
[ 197] var _ planNode = &splitNode{} | |
[ 198] var _ planNode = &unionNode{} | |
[ 199] var _ planNode = &updateNode{} | |
[ 200] var _ planNode = &upsertNode{} | |
[ 201] var _ planNode = &valueGenerator{} | |
[ 202] var _ planNode = &valuesNode{} | |
[ 203] var _ planNode = &windowNode{} | |
[ 204] var _ planNode = &CreateUserNode{} | |
[ 205] var _ planNode = &DropUserNode{} | |
[ 206] | |
[ 207] var _ planNodeFastPath = &CreateUserNode{} | |
[ 208] var _ planNodeFastPath = &DropUserNode{} | |
[ 209] var _ planNodeFastPath = &alterUserSetPasswordNode{} | |
[ 210] var _ planNodeFastPath = &createTableNode{} | |
[ 211] var _ planNodeFastPath = &deleteNode{} | |
[ 212] var _ planNodeFastPath = &setZoneConfigNode{} | |
[ 213] var _ planNodeFastPath = &upsertNode{} | |
[ 214] | |
[ 215] // planNodeRequireSpool serves as marker for nodes whose parent must | |
[ 216] // ensure that the node is fully run to completion (and the results | |
[ 217] // spooled) during the start phase. This is currently implemented by | |
[ 218] // all mutation statements except for upsert. | |
[ 219] type planNodeRequireSpool interface { | |
[ 220] requireSpool() | |
[ 221] } | |
[ 222] | |
[ 223] var _ planNodeRequireSpool = &insertNode{} | |
[ 224] var _ planNodeRequireSpool = &deleteNode{} | |
[ 225] var _ planNodeRequireSpool = &updateNode{} | |
[ 226] | |
[ 227] // planNodeSpool serves as marker for nodes that can perform all their | |
[ 228] // execution during the start phase. This is different from the "fast | |
[ 229] // path" interface because a node that performs all its execution | |
[ 230] // during the start phase might still have some result rows and thus | |
[ 231] // not implement the fast path. | |
[ 232] // | |
[ 233] // This interface exists for the following optimization: nodes | |
[ 234] // that require spooling but are the children of a spooled node | |
[ 235] // do not require the introduction of an explicit spool. | |
[ 236] type planNodeSpooled interface { | |
[ 237] spooled() | |
[ 238] } | |
[ 239] | |
[ 240] var _ planNodeSpooled = &upsertNode{} | |
[ 241] var _ planNodeSpooled = &spoolNode{} | |
[ 242] | |
[ 243] // planTop is the struct that collects the properties | |
[ 244] // of an entire plan. | |
[ 245] // Note: some additional per-statement state is also stored in | |
[ 246] // semaCtx (placeholders). | |
[ 247] // TODO(jordan): investigate whether/how per-plan state like | |
[ 248] // placeholder data can be concentrated in a single struct. | |
[ 249] type planTop struct { | |
[ 250] // AST is the syntax tree for the current statement. | |
[ 251] AST tree.Statement | |
[ 252] | |
[ 253] // plan is the top-level node of the logical plan. | |
[ 254] plan planNode | |
[ 255] | |
[ 256] // deps, if non-nil, collects the table/view dependencies for this query. | |
[ 257] // Any planNode constructors that resolves a table name or reference in the query | |
[ 258] // to a descriptor must register this descriptor into planDeps. | |
[ 259] // This is (currently) used by CREATE VIEW. | |
[ 260] // TODO(knz): Remove this in favor of a better encapsulated mechanism. | |
[ 261] deps planDependencies | |
[ 262] | |
[ 263] // cteNameEnvironment collects the mapping from common table expression alias | |
[ 264] // to the planNodes that represent their source. | |
[ 265] cteNameEnvironment cteNameEnvironment | |
[ 266] | |
[ 267] // hasStar collects whether any star expansion has occurred during | |
[ 268] // logical plan construction. This is used by CREATE VIEW until | |
[ 269] // #10028 is addressed. | |
[ 270] hasStar bool | |
[ 271] | |
[ 272] // subqueryPlans contains all the sub-query plans. | |
[ 273] subqueryPlans []subquery | |
[ 274] | |
[ 275] // plannedExecute is true if this planner has planned an EXECUTE statement. | |
[ 276] plannedExecute bool | |
[ 277] | |
[ 278] // auditEvents becomes non-nil if any of the descriptors used by | |
[ 279] // current statement is causing an auditing event. See exec_log.go. | |
[ 280] auditEvents []auditEvent | |
[ 281] } | |
[ 282] | |
[ 283] // makePlan implements the Planner interface. It populates the | |
[ 284] // planner's curPlan field. | |
[ 285] // | |
[ 286] // The caller is responsible for populating the placeholders | |
[ 287] // beforehand (currently in semaCtx.Placeholders). | |
[ 288] // | |
[ 289] // After makePlan(), the caller should be careful to also call | |
[ 290] // p.curPlan.Close(). | |
[ 291] func (p *planner) makePlan(ctx context.Context, stmt Statement) error { | |
[ 292] // Reinitialize. | |
[ 293] p.curPlan = planTop{AST: stmt.AST} | |
[ 294] | |
[ 295] var err error | |
[ 296] p.curPlan.plan, err = p.newPlan(ctx, stmt.AST, nil /*desiredTypes*/) | |
[ 297] if err != nil { | |
[ 298] return err | |
[ 299] } | |
[ 300] cols := planColumns(p.curPlan.plan) | |
[ 301] if stmt.ExpectedTypes != nil { | |
[ 302] if !stmt.ExpectedTypes.TypesEqual(cols) { | |
[ 303] return pgerror.NewError(pgerror.CodeFeatureNotSupportedError, | |
[ 304] "cached plan must not change result type") | |
[ 305] } | |
[ 306] } | |
[ 307] if err := p.semaCtx.Placeholders.AssertAllAssigned(); err != nil { | |
[ 308] // We need to close in case there were any subqueries created. | |
[ 309] p.curPlan.close(ctx) | |
[ 310] return err | |
[ 311] } | |
[ 312] | |
[ 313] // Ensure that any hidden result column is effectively hidden. | |
[ 314] // We do this before optimization below so that the needed | |
[ 315] // column optimization kills the hidden columns. | |
[ 316] p.curPlan.plan, err = p.hideHiddenColumns(ctx, p.curPlan.plan, cols) | |
[ 317] if err != nil { | |
[ 318] p.curPlan.close(ctx) | |
[ 319] return err | |
[ 320] } | |
[ 321] | |
[ 322] needed := allColumns(p.curPlan.plan) | |
[ 323] p.curPlan.plan, err = p.optimizePlan(ctx, p.curPlan.plan, needed) | |
[ 324] if err != nil { | |
[ 325] p.curPlan.close(ctx) | |
[ 326] return err | |
[ 327] } | |
[ 328] | |
[ 329] // Now do the same work for all sub-queries. | |
[ 330] for i := range p.curPlan.subqueryPlans { | |
[ 331] if err := p.optimizeSubquery(ctx, &p.curPlan.subqueryPlans[i]); err != nil { | |
[ 332] p.curPlan.close(ctx) | |
[ 333] return err | |
[ 334] } | |
[ 335] } | |
[ 336] | |
[ 337] if log.V(3) { | |
[ 338] log.Infof(ctx, "statement %s compiled to:\n%s", stmt, | |
[ 339] planToString(ctx, p.curPlan.plan, p.curPlan.subqueryPlans)) | |
[ 340] } | |
[ 341] | |
[ 342] return nil | |
[ 343] } | |
[ 344] | |
[ 345] // makeOptimizerPlan is an alternative to makePlan which uses the (experimental) | |
[ 346] // optimizer. | |
[ 347] func (p *planner) makeOptimizerPlan(ctx context.Context, stmt Statement) error { | |
[ 348] // execEngine is both an exec.Factory and an opt.Catalog. cleanup is not | |
[ 349] // required on the engine, since planner is cleaned up elsewhere. | |
[ 350] eng := newExecEngine(p, nil) | |
[ 351] defer eng.Close() | |
[ 352] | |
[ 353] o := xform.NewOptimizer(p.EvalContext()) | |
[ 354] bld := optbuilder.New(ctx, &p.semaCtx, p.EvalContext(), eng.Catalog(), o.Factory(), stmt.AST) | |
[ 355] root, props, err := bld.Build() | |
[ 356] if err != nil { | |
[ 357] return err | |
[ 358] } | |
[ 359] | |
[ 360] ev := o.Optimize(root, props) | |
[ 361] | |
[ 362] node, err := execbuilder.New(eng, ev).Build() | |
[ 363] if err != nil { | |
[ 364] return err | |
[ 365] } | |
[ 366] p.curPlan.plan = node.(planNode) | |
[ 367] return nil | |
[ 368] } | |
[ 369] | |
[ 370] // hideHiddenColumn ensures that if the plan is returning some hidden | |
[ 371] // column(s), it is wrapped into a renderNode which only renders the | |
[ 372] // visible columns. | |
[ 373] func (p *planner) hideHiddenColumns( | |
[ 374] ctx context.Context, plan planNode, cols sqlbase.ResultColumns, | |
[ 375] ) (planNode, error) { | |
[ 376] hasHidden := false | |
[ 377] for i := range cols { | |
[ 378] if cols[i].Hidden { | |
[ 379] hasHidden = true | |
[ 380] break | |
[ 381] } | |
[ 382] } | |
[ 383] if !hasHidden { | |
[ 384] // Nothing to do. | |
[ 385] return plan, nil | |
[ 386] } | |
[ 387] | |
[ 388] var tn tree.TableName | |
[ 389] newPlan, err := p.insertRender(ctx, plan, &tn) | |
[ 390] if err != nil { | |
[ 391] // Don't return a nil plan on error -- the caller must be able to | |
[ 392] // Close() it even if the replacement fails. | |
[ 393] return plan, err | |
[ 394] } | |
[ 395] | |
[ 396] return newPlan, nil | |
[ 397] } | |
[ 398] | |
[ 399] // close ensures that the plan's resources have been deallocated. | |
[ 400] func (p *planTop) close(ctx context.Context) { | |
[ 401] if p.plan != nil { | |
[ 402] p.plan.Close(ctx) | |
[ 403] p.plan = nil | |
[ 404] } | |
[ 405] | |
[ 406] for i := range p.subqueryPlans { | |
[ 407] // Once a subquery plan has been evaluated, it already closes its | |
[ 408] // plan. | |
[ 409] if p.subqueryPlans[i].plan != nil { | |
[ 410] p.subqueryPlans[i].plan.Close(ctx) | |
[ 411] p.subqueryPlans[i].plan = nil | |
[ 412] } | |
[ 413] } | |
[ 414] } | |
[ 415] | |
[ 416] // start starts the plan. | |
[ 417] func (p *planTop) start(params runParams) error { | |
[ 418] if err := p.evalSubqueries(params); err != nil { | |
[ 419] return err | |
[ 420] } | |
[ 421] return startPlan(params, p.plan) | |
[ 422] } | |
[ 423] | |
[ 424] // columns retrieves the plan's columns. | |
[ 425] func (p *planTop) columns() sqlbase.ResultColumns { | |
[ 426] return planColumns(p.plan) | |
[ 427] } | |
[ 428] | |
[ 429] func (p *planTop) collectSpans(params runParams) (readSpans, writeSpans roachpb.Spans, err error) { | |
[ 430] readSpans, writeSpans, err = collectSpans(params, p.plan) | |
[ 431] if err != nil { | |
[ 432] return nil, nil, err | |
[ 433] } | |
[ 434] for i := range params.p.curPlan.subqueryPlans { | |
[ 435] reads, writes, err := collectSpans(params, params.p.curPlan.subqueryPlans[i].plan) | |
[ 436] if err != nil { | |
[ 437] return nil, nil, err | |
[ 438] } | |
[ 439] readSpans = append(readSpans, reads...) | |
[ 440] writeSpans = append(writeSpans, writes...) | |
[ 441] } | |
[ 442] return readSpans, writeSpans, nil | |
[ 443] } | |
[ 444] | |
[ 445] // startPlan starts the given plan and all its sub-query nodes. | |
[ 446] func startPlan(params runParams, plan planNode) error { | |
[ 447] // Now start execution. | |
[ 448] if err := startExec(params, plan); err != nil { | |
[ 449] return err | |
[ 450] } | |
[ 451] | |
[ 452] // Finally, trigger limit propagation through the plan. The actual | |
[ 453] // LIMIT values will have been evaluated by startExec(). | |
[ 454] params.p.setUnlimited(plan) | |
[ 455] | |
[ 456] return nil | |
[ 457] } | |
[ 458] | |
[ 459] // execStartable is implemented by planNodes that have an initial | |
[ 460] // execution step. | |
[ 461] type execStartable interface { | |
[ 462] startExec(params runParams) error | |
[ 463] } | |
[ 464] | |
[ 465] // autoCommitNode is implemented by planNodes that might be able to commit the | |
[ 466] // KV txn in which they operate. Some nodes might want to do this to take | |
[ 467] // advantage of the 1PC optimization in case they're running as an implicit | |
[ 468] // transaction. | |
[ 469] // Only the top-level node in a plan is allowed to auto-commit. A node that | |
[ 470] // choses to do so has to be cognizant of all its children: it needs to only | |
[ 471] // auto-commit after all the children have finished performing KV operations | |
[ 472] // and, more generally, after the plan is guaranteed to not produce any | |
[ 473] // execution errors (in case of an error anywhere in the query, we do not want | |
[ 474] // to commit the txn). | |
[ 475] type autoCommitNode interface { | |
[ 476] // enableAutoCommit is called on the root planNode (if it implements this | |
[ 477] // interface). | |
[ 478] enableAutoCommit() | |
[ 479] } | |
[ 480] | |
[ 481] var _ autoCommitNode = &createTableNode{} | |
[ 482] var _ autoCommitNode = &delayedNode{} | |
[ 483] var _ autoCommitNode = &deleteNode{} | |
[ 484] var _ autoCommitNode = &insertNode{} | |
[ 485] var _ autoCommitNode = &updateNode{} | |
[ 486] var _ autoCommitNode = &upsertNode{} | |
[ 487] | |
[ 488] // startExec calls startExec() on each planNode that supports | |
[ 489] // execStartable using a depth-first, post-order traversal. | |
[ 490] // The subqueries, if any, are also started. | |
[ 491] // | |
[ 492] // Reminder: walkPlan() ensures that subqueries and sub-plans are | |
[ 493] // started before startExec() is called. | |
[ 494] func startExec(params runParams, plan planNode) error { | |
[ 495] o := planObserver{ | |
[ 496] enterNode: func(ctx context.Context, _ string, p planNode) (bool, error) { | |
[ 497] switch p.(type) { | |
[ 498] case *explainPlanNode, *explainDistSQLNode: | |
[ 499] // Do not recurse: we're not starting the plan if we just show its structure with EXPLAIN. | |
[ 500] return false, nil | |
[ 501] case *showTraceNode: | |
[ 502] // showTrace needs to override the params struct, and does so in its startExec() method. | |
[ 503] return false, nil | |
[ 504] case *createStatsNode: | |
[ 505] return false, errors.Errorf("statistics can only be created via DistSQL") | |
[ 506] } | |
[ 507] return true, nil | |
[ 508] }, | |
[ 509] leaveNode: func(_ string, n planNode) error { | |
[ 510] if s, ok := n.(execStartable); ok { | |
[ 511] return s.startExec(params) | |
[ 512] } | |
[ 513] return nil | |
[ 514] }, | |
[ 515] } | |
[ 516] return walkPlan(params.ctx, plan, o) | |
[ 517] } | |
[ 518] | |
[ 519] func (p *planner) maybePlanHook(ctx context.Context, stmt tree.Statement) (planNode, error) { | |
[ 520] // TODO(dan): This iteration makes the plan dispatch no longer constant | |
[ 521] // time. We could fix that with a map of `reflect.Type` but including | |
[ 522] // reflection in such a primary codepath is unfortunate. Instead, the | |
[ 523] // upcoming IR work will provide unique numeric type tags, which will | |
[ 524] // elegantly solve this. | |
[ 525] for _, planHook := range planHooks { | |
[ 526] if fn, header, err := planHook(ctx, stmt, p); err != nil { | |
[ 527] return nil, err | |
[ 528] } else if fn != nil { | |
[ 529] return &hookFnNode{f: fn, header: header}, nil | |
[ 530] } | |
[ 531] } | |
[ 532] for _, planHook := range wrappedPlanHooks { | |
[ 533] if node, err := planHook(ctx, stmt, p); err != nil { | |
[ 534] return nil, err | |
[ 535] } else if node != nil { | |
[ 536] return node, err | |
[ 537] } | |
[ 538] } | |
[ 539] | |
[ 540] return nil, nil | |
[ 541] } | |
[ 542] | |
[ 543] // delegateQuery creates a plan for a given SQL query. | |
[ 544] // In addition, the caller can specify an additional validation | |
[ 545] // function (initialCheck) that will be ran and checked for errors | |
[ 546] // during plan optimization. This is meant for checks that cannot be | |
[ 547] // run during a SQL prepare operation. | |
[ 548] func (p *planner) delegateQuery( | |
[ 549] ctx context.Context, | |
[ 550] name string, | |
[ 551] sql string, | |
[ 552] initialCheck func(ctx context.Context) error, | |
[ 553] desiredTypes []types.T, | |
[ 554] ) (planNode, error) { | |
[ 555] // log.VEventf(ctx, 2, "delegated query: %q", sql) | |
[ 556] | |
[ 557] // Prepare the sub-plan. | |
[ 558] stmt, err := parser.ParseOne(sql) | |
[ 559] if err != nil { | |
[ 560] return nil, err | |
[ 561] } | |
[ 562] plan, err := p.newPlan(ctx, stmt, desiredTypes) | |
[ 563] if err != nil { | |
[ 564] return nil, err | |
[ 565] } | |
[ 566] | |
[ 567] if initialCheck == nil { | |
[ 568] return plan, nil | |
[ 569] } | |
[ 570] | |
[ 571] // To enable late calling into initialCheck, we use a delayedNode. | |
[ 572] return &delayedNode{ | |
[ 573] name: name, | |
[ 574] | |
[ 575] // The columns attribute cannot be a straight-up reference to the sub-plan's | |
[ 576] // own columns, because they can be modified in-place by setNeededColumns(). | |
[ 577] columns: append(sqlbase.ResultColumns(nil), planColumns(plan)...), | |
[ 578] | |
[ 579] // The delayed constructor's only responsibility is to call | |
[ 580] // initialCheck() - the plan is already constructed. | |
[ 581] constructor: func(ctx context.Context, _ *planner) (planNode, error) { | |
[ 582] if err := initialCheck(ctx); err != nil { | |
[ 583] return nil, err | |
[ 584] } | |
[ 585] return plan, nil | |
[ 586] }, | |
[ 587] | |
[ 588] // Breaking with the common usage pattern of delayedNode, where | |
[ 589] // the plan attribute is initially nil (the constructor creates | |
[ 590] // it), here we prepopulate the field with the sub-plan created | |
[ 591] // above. We do this instead of simply returning the newly created | |
[ 592] // sub-plan in a constructor closure, to ensure the sub-plan is | |
[ 593] // properly Close()d if the delayedNode is discarded before its | |
[ 594] // constructor is called. | |
[ 595] plan: plan, | |
[ 596] }, nil | |
[ 597] } | |
[ 598] | |
[ 599] // newPlan constructs a planNode from a statement. This is used | |
[ 600] // recursively by the various node constructors. | |
[ 601] func (p *planner) newPlan( | |
[ 602] ctx context.Context, stmt tree.Statement, desiredTypes []types.T, | |
[ 603] ) (planNode, error) { | |
[ 604] tracing.AnnotateTrace() | |
[ 605] | |
[ 606] // This will set the system DB trigger for transactions containing | |
[ 607] // schema-modifying statements that have no effect, such as | |
[ 608] // `BEGIN; INSERT INTO ...; CREATE TABLE IF NOT EXISTS ...; COMMIT;` | |
[ 609] // where the table already exists. This will generate some false | |
[ 610] // refreshes, but that's expected to be quite rare in practice. | |
[ 611] canModifySchema := tree.CanModifySchema(stmt) | |
[ 612] if canModifySchema { | |
[ 613] if err := p.txn.SetSystemConfigTrigger(); err != nil { | |
[ 614] return nil, errors.Wrap(err, | |
[ 615] "schema change statement cannot follow a statement that has written in the same transaction") | |
[ 616] } | |
[ 617] } | |
[ 618] | |
[ 619] if p.EvalContext().TxnReadOnly { | |
[ 620] if canModifySchema || tree.CanWriteData(stmt) { | |
[ 621] return nil, pgerror.NewErrorf(pgerror.CodeReadOnlySQLTransactionError, | |
[ 622] "cannot execute %s in a read-only transaction", stmt.StatementTag()) | |
[ 623] } | |
[ 624] } | |
[ 625] | |
[ 626] if plan, err := p.maybePlanHook(ctx, stmt); plan != nil || err != nil { | |
[ 627] return plan, err | |
[ 628] } | |
[ 629] | |
[ 630] switch n := stmt.(type) { | |
[ 631] case *tree.AlterIndex: | |
[ 632] return p.AlterIndex(ctx, n) | |
[ 633] case *tree.AlterTable: | |
[ 634] return p.AlterTable(ctx, n) | |
[ 635] case *tree.AlterSequence: | |
[ 636] return p.AlterSequence(ctx, n) | |
[ 637] case *tree.AlterUserSetPassword: | |
[ 638] return p.AlterUserSetPassword(ctx, n) | |
[ 639] case *tree.CancelQuery: | |
[ 640] return p.CancelQuery(ctx, n) | |
[ 641] case *tree.CancelJob: | |
[ 642] return p.CancelJob(ctx, n) | |
[ 643] case *tree.Scrub: | |
[ 644] return p.Scrub(ctx, n) | |
[ 645] case *tree.CreateDatabase: | |
[ 646] return p.CreateDatabase(ctx, n) | |
[ 647] case *tree.CreateIndex: | |
[ 648] return p.CreateIndex(ctx, n) | |
[ 649] case *tree.CreateTable: | |
[ 650] return p.CreateTable(ctx, n) | |
[ 651] case *tree.CreateUser: | |
[ 652] return p.CreateUser(ctx, n) | |
[ 653] case *tree.CreateView: | |
[ 654] return p.CreateView(ctx, n) | |
[ 655] case *tree.CreateSequence: | |
[ 656] return p.CreateSequence(ctx, n) | |
[ 657] case *tree.CreateStats: | |
[ 658] return p.CreateStatistics(ctx, n) | |
[ 659] case *tree.Deallocate: | |
[ 660] return p.Deallocate(ctx, n) | |
[ 661] case *tree.Delete: | |
[ 662] return p.Delete(ctx, n, desiredTypes) | |
[ 663] case *tree.Discard: | |
[ 664] return p.Discard(ctx, n) | |
[ 665] case *tree.DropDatabase: | |
[ 666] return p.DropDatabase(ctx, n) | |
[ 667] case *tree.DropIndex: | |
[ 668] return p.DropIndex(ctx, n) | |
[ 669] case *tree.DropTable: | |
[ 670] return p.DropTable(ctx, n) | |
[ 671] case *tree.DropView: | |
[ 672] return p.DropView(ctx, n) | |
[ 673] case *tree.DropSequence: | |
[ 674] return p.DropSequence(ctx, n) | |
[ 675] case *tree.DropUser: | |
[ 676] return p.DropUser(ctx, n) | |
[ 677] case *tree.Execute: | |
[ 678] return p.Execute(ctx, n) | |
[ 679] case *tree.Explain: | |
[ 680] return p.Explain(ctx, n) | |
[ 681] case *tree.Grant: | |
[ 682] return p.Grant(ctx, n) | |
[ 683] case *tree.Insert: | |
[ 684] return p.Insert(ctx, n, desiredTypes) | |
[ 685] case *tree.ParenSelect: | |
[ 686] return p.newPlan(ctx, n.Select, desiredTypes) | |
[ 687] case *tree.PauseJob: | |
[ 688] return p.PauseJob(ctx, n) | |
[ 689] case *tree.TestingRelocate: | |
[ 690] return p.TestingRelocate(ctx, n) | |
[ 691] case *tree.RenameColumn: | |
[ 692] return p.RenameColumn(ctx, n) | |
[ 693] case *tree.RenameDatabase: | |
[ 694] return p.RenameDatabase(ctx, n) | |
[ 695] case *tree.RenameIndex: | |
[ 696] return p.RenameIndex(ctx, n) | |
[ 697] case *tree.RenameTable: | |
[ 698] return p.RenameTable(ctx, n) | |
[ 699] case *tree.ResumeJob: | |
[ 700] return p.ResumeJob(ctx, n) | |
[ 701] case *tree.Revoke: | |
[ 702] return p.Revoke(ctx, n) | |
[ 703] case *tree.Scatter: | |
[ 704] return p.Scatter(ctx, n) | |
[ 705] case *tree.Select: | |
[ 706] return p.Select(ctx, n, desiredTypes) | |
[ 707] case *tree.SelectClause: | |
[ 708] return p.SelectClause(ctx, n, nil /* orderBy */, nil /* limit */, nil, /* with */ | |
[ 709] desiredTypes, publicColumns) | |
[ 710] case *tree.SetClusterSetting: | |
[ 711] return p.SetClusterSetting(ctx, n) | |
[ 712] case *tree.SetZoneConfig: | |
[ 713] return p.SetZoneConfig(ctx, n) | |
[ 714] case *tree.SetVar: | |
[ 715] return p.SetVar(ctx, n) | |
[ 716] case *tree.SetTransaction: | |
[ 717] return p.SetTransaction(n) | |
[ 718] case *tree.SetSessionCharacteristics: | |
[ 719] return p.SetSessionCharacteristics(n) | |
[ 720] case *tree.ShowClusterSetting: | |
[ 721] return p.ShowClusterSetting(ctx, n) | |
[ 722] case *tree.ShowVar: | |
[ 723] return p.ShowVar(ctx, n) | |
[ 724] case *tree.ShowColumns: | |
[ 725] return p.ShowColumns(ctx, n) | |
[ 726] case *tree.ShowConstraints: | |
[ 727] return p.ShowConstraints(ctx, n) | |
[ 728] case *tree.ShowCreateTable: | |
[ 729] return p.ShowCreateTable(ctx, n) | |
[ 730] case *tree.ShowCreateView: | |
[ 731] return p.ShowCreateView(ctx, n) | |
[ 732] case *tree.ShowCreateSequence: | |
[ 733] return p.ShowCreateSequence(ctx, n) | |
[ 734] case *tree.ShowDatabases: | |
[ 735] return p.ShowDatabases(ctx, n) | |
[ 736] case *tree.ShowGrants: | |
[ 737] return p.ShowGrants(ctx, n) | |
[ 738] case *tree.ShowHistogram: | |
[ 739] return p.ShowHistogram(ctx, n) | |
[ 740] case *tree.ShowIndex: | |
[ 741] return p.ShowIndex(ctx, n) | |
[ 742] case *tree.ShowQueries: | |
[ 743] return p.ShowQueries(ctx, n) | |
[ 744] case *tree.ShowJobs: | |
[ 745] return p.ShowJobs(ctx, n) | |
[ 746] case *tree.ShowRoleGrants: | |
[ 747] return p.ShowRoleGrants(ctx, n) | |
[ 748] case *tree.ShowRoles: | |
[ 749] return p.ShowRoles(ctx, n) | |
[ 750] case *tree.ShowSessions: | |
[ 751] return p.ShowSessions(ctx, n) | |
[ 752] case *tree.ShowTableStats: | |
[ 753] return p.ShowTableStats(ctx, n) | |
[ 754] case *tree.ShowSyntax: | |
[ 755] return p.ShowSyntax(ctx, n) | |
[ 756] case *tree.ShowTables: | |
[ 757] return p.ShowTables(ctx, n) | |
[ 758] case *tree.ShowSchemas: | |
[ 759] return p.ShowSchemas(ctx, n) | |
[ 760] case *tree.ShowTrace: | |
[ 761] return p.ShowTrace(ctx, n) | |
[ 762] case *tree.ShowTransactionStatus: | |
[ 763] return p.ShowTransactionStatus(ctx) | |
[ 764] case *tree.ShowUsers: | |
[ 765] return p.ShowUsers(ctx, n) | |
[ 766] case *tree.ShowZoneConfig: | |
[ 767] return p.ShowZoneConfig(ctx, n) | |
[ 768] case *tree.ShowRanges: | |
[ 769] return p.ShowRanges(ctx, n) | |
[ 770] case *tree.ShowFingerprints: | |
[ 771] return p.ShowFingerprints(ctx, n) | |
[ 772] case *tree.Split: | |
[ 773] return p.Split(ctx, n) | |
[ 774] case *tree.Truncate: | |
[ 775] if err := p.txn.SetSystemConfigTrigger(); err != nil { | |
[ 776] return nil, err | |
[ 777] } | |
[ 778] return p.Truncate(ctx, n) | |
[ 779] case *tree.UnionClause: | |
[ 780] return p.Union(ctx, n, desiredTypes) | |
[ 781] case *tree.Update: | |
[ 782] return p.Update(ctx, n, desiredTypes) | |
[ 783] case *tree.ValuesClause: | |
[ 784] return p.Values(ctx, n, desiredTypes) | |
[ 785] default: | |
[ 786] return nil, errors.Errorf("unknown statement type: %T", stmt) | |
[ 787] } | |
[ 788] } | |
[ 789] | |
[ 790] // prepare constructs the logical plan for the statement. This is | |
[ 791] // needed both to type placeholders and to inform pgwire of the types | |
[ 792] // of the result columns. All statements that either support | |
[ 793] // placeholders or have result columns must be handled here. | |
[ 794] // The resulting plan is stored in p.curPlan. | |
[ 795] func (p *planner) prepare(ctx context.Context, stmt tree.Statement) error { | |
[ 796] // Reinitialize. | |
[ 797] p.curPlan = planTop{AST: stmt} | |
[ 798] | |
[ 799] // Prepare the plan. | |
[ 800] plan, err := p.doPrepare(ctx, stmt) | |
[ 801] if err != nil { | |
[ 802] return err | |
[ 803] } | |
[ 804] | |
[ 805] // Store the plan for later use. | |
[ 806] p.curPlan.plan = plan | |
[ 807] | |
[ 808] return nil | |
[ 809] } | |
[ 810] | |
[ 811] func (p *planner) doPrepare(ctx context.Context, stmt tree.Statement) (planNode, error) { | |
[ 812] if plan, err := p.maybePlanHook(ctx, stmt); plan != nil || err != nil { | |
[ 813] return plan, err | |
[ 814] } | |
[ 815] p.isPreparing = true | |
[ 816] | |
[ 817] switch n := stmt.(type) { | |
[ 818] case *tree.AlterUserSetPassword: | |
[ 819] return p.AlterUserSetPassword(ctx, n) | |
[ 820] case *tree.CancelQuery: | |
[ 821] return p.CancelQuery(ctx, n) | |
[ 822] case *tree.CancelJob: | |
[ 823] return p.CancelJob(ctx, n) | |
[ 824] case *tree.CreateUser: | |
[ 825] return p.CreateUser(ctx, n) | |
[ 826] case *tree.CreateTable: | |
[ 827] return p.CreateTable(ctx, n) | |
[ 828] case *tree.Delete: | |
[ 829] return p.Delete(ctx, n, nil) | |
[ 830] case *tree.DropUser: | |
[ 831] return p.DropUser(ctx, n) | |
[ 832] case *tree.Explain: | |
[ 833] return p.Explain(ctx, n) | |
[ 834] case *tree.Insert: | |
[ 835] return p.Insert(ctx, n, nil) | |
[ 836] case *tree.PauseJob: | |
[ 837] return p.PauseJob(ctx, n) | |
[ 838] case *tree.ResumeJob: | |
[ 839] return p.ResumeJob(ctx, n) | |
[ 840] case *tree.Select: | |
[ 841] return p.Select(ctx, n, nil) | |
[ 842] case *tree.SelectClause: | |
[ 843] return p.SelectClause(ctx, n, nil /* orderBy */, nil /* limit */, nil, /* with */ | |
[ 844] nil /* desiredTypes */, publicColumns) | |
[ 845] case *tree.SetClusterSetting: | |
[ 846] return p.SetClusterSetting(ctx, n) | |
[ 847] case *tree.SetVar: | |
[ 848] return p.SetVar(ctx, n) | |
[ 849] case *tree.ShowClusterSetting: | |
[ 850] return p.ShowClusterSetting(ctx, n) | |
[ 851] case *tree.ShowVar: | |
[ 852] return p.ShowVar(ctx, n) | |
[ 853] case *tree.ShowCreateTable: | |
[ 854] return p.ShowCreateTable(ctx, n) | |
[ 855] case *tree.ShowCreateView: | |
[ 856] return p.ShowCreateView(ctx, n) | |
[ 857] case *tree.ShowCreateSequence: | |
[ 858] return p.ShowCreateSequence(ctx, n) | |
[ 859] case *tree.ShowColumns: | |
[ 860] return p.ShowColumns(ctx, n) | |
[ 861] case *tree.ShowDatabases: | |
[ 862] return p.ShowDatabases(ctx, n) | |
[ 863] case *tree.ShowGrants: | |
[ 864] return p.ShowGrants(ctx, n) | |
[ 865] case *tree.ShowIndex: | |
[ 866] return p.ShowIndex(ctx, n) | |
[ 867] case *tree.ShowConstraints: | |
[ 868] return p.ShowConstraints(ctx, n) | |
[ 869] case *tree.ShowQueries: | |
[ 870] return p.ShowQueries(ctx, n) | |
[ 871] case *tree.ShowJobs: | |
[ 872] return p.ShowJobs(ctx, n) | |
[ 873] case *tree.ShowRoleGrants: | |
[ 874] return p.ShowRoleGrants(ctx, n) | |
[ 875] case *tree.ShowRoles: | |
[ 876] return p.ShowRoles(ctx, n) | |
[ 877] case *tree.ShowSessions: | |
[ 878] return p.ShowSessions(ctx, n) | |
[ 879] case *tree.ShowTables: | |
[ 880] return p.ShowTables(ctx, n) | |
[ 881] case *tree.ShowSchemas: | |
[ 882] return p.ShowSchemas(ctx, n) | |
[ 883] case *tree.ShowTrace: | |
[ 884] return p.ShowTrace(ctx, n) | |
[ 885] case *tree.ShowUsers: | |
[ 886] return p.ShowUsers(ctx, n) | |
[ 887] case *tree.ShowTransactionStatus: | |
[ 888] return p.ShowTransactionStatus(ctx) | |
[ 889] case *tree.ShowRanges: | |
[ 890] return p.ShowRanges(ctx, n) | |
[ 891] case *tree.Split: | |
[ 892] return p.Split(ctx, n) | |
[ 893] case *tree.TestingRelocate: | |
[ 894] return p.TestingRelocate(ctx, n) | |
[ 895] case *tree.Scatter: | |
[ 896] return p.Scatter(ctx, n) | |
[ 897] case *tree.Update: | |
[ 898] return p.Update(ctx, n, nil) | |
[ 899] default: | |
[ 900] // Other statement types do not have result columns and do not | |
[ 901] // support placeholders so there is no need for any special | |
[ 902] // handling here. | |
[ 903] return nil, nil | |
[ 904] } | |
[ 905] } | |
[INFO][00:17:52] Applied 'ShowPatchAction' on 'pkg/sql/plan.go' from 'GofmtBear'. | |
[WARNING][00:17:52] GoVetBear: This result has no patch attached. | |
pkg/sql/plan.go | |
[ 15] package·sql | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! expected type, found '=' | |
[WARNING][00:17:53] GoVetBear: This result has no patch attached. | |
pkg/sql/check.go | |
[ 41] » » From:··&tree.From{Tables:·tree.TableExprs{tableName}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.TableExprs composite literal uses unkeyed fields | |
[WARNING][00:17:53] GoVetBear: This result has no patch attached. | |
pkg/sql/sem/tree/expr_test.go | |
[ 52] » » q·:=·tree.UnresolvedName{NumParts:·1,·Parts:·tree.NameParts{tc.in}} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.NameParts composite literal uses unkeyed fields | |
[WARNING][00:17:54] GoVetBear: This result has no patch attached. | |
pkg/sql/table.go | |
[ 602] » » DescriptorIDs:·sqlbase.IDs{tableDesc.GetID()}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.IDs composite literal uses unkeyed fields | |
[WARNING][00:17:54] GoVetBear: This result has no patch attached. | |
pkg/sql/select_name_resolution.go | |
[ 171] » » » » » » » NumParts:·1,·Parts:·tree.NameParts{"count_rows"}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.NameParts composite literal uses unkeyed fields | |
[WARNING][00:17:56] GoVetBear: This result has no patch attached. | |
pkg/sql/distsqlrun/cluster_test.go | |
[ 369] » » » rightRows·=·append(rightRows,·sqlbase.EncDatumRow{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.EncDatumRow composite literal uses unkeyed fields | |
**** GofmtBear [Section <empty> | Severity NORMAL] **** | |
! ! Formatting can be improved. | |
[----] /home/palash25/Dev/cockroach/pkg/sql/sem/tree/name_part.go | |
[++++] /home/palash25/Dev/cockroach/pkg/sql/sem/tree/name_part.go | |
[ 1] // Copyright 2016 The Cockroach Authors. | |
[ 2] // | |
[ 3] // Licensed under the Apache License, Version 2.0 (the "License"); | |
[ 4] // you may not use this file except in compliance with the License. | |
[ 5] // You may obtain a copy of the License at | |
[ 6] // | |
[ 7] // http://www.apache.org/licenses/LICENSE-2.0 | |
[ 8] // | |
[ 9] // Unless required by applicable law or agreed to in writing, software | |
[ 10] // distributed under the License is distributed on an "AS IS" BASIS, | |
[ 11] // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
[ 12] // implied. See the License for the specific language governing | |
[ 13] // permissions and limitations under the License. | |
[ 14] | |
[ 15] package tree | |
[ 16] | |
[ 17] import ( | |
[ 18] "github.com/cockroachdb/cockroach/pkg/sql/lex" | |
[ 19] ) | |
[ 20] | |
[ 21] // A Name is an SQL identifier. | |
[ 22] // | |
[ 23] // In general, a Name is the result of parsing a name nonterminal, which is used | |
[ 24] // in the grammar where reserved keywords cannot be distinguished from | |
[ 25] // identifiers. A Name that matches a reserved keyword must thus be quoted when | |
[ 26] // formatted. (Names also need quoting for a variety of other reasons; see | |
[ 27] // isBareIdentifier.) | |
[ 28] // | |
[ 29] // For historical reasons, some Names are instead the result of parsing | |
[ 30] // `unrestricted_name` nonterminals. See UnrestrictedName for details. | |
[ 31] type Name string | |
[ 32] | |
[ 33] // Format implements the NodeFormatter interface. | |
[ 34] func (n *Name) Format(ctx *FmtCtx) { | |
[ 35] f := ctx.flags | |
[ 36] if f.HasFlags(FmtAnonymize) { | |
[ 37] ctx.WriteByte('_') | |
[ 38] } else { | |
[ 39] lex.EncodeRestrictedSQLIdent(ctx.Buffer, string(*n), f.EncodeFlags()) | |
[ 40] } | |
[ 41] } | |
[ 42] | |
[ 43] // NameStringP escapes an identifier stored in a heap string to a SQL | |
[ 44] // identifier, avoiding a heap allocation. | |
[ 45] func NameStringP(s *string) string { | |
[ 46] return ((*Name)(s)).String() | |
[ 47] } | |
[ 48] | |
[ 49] // NameString escapes an identifier stored in a string to a SQL | |
[ 50] // identifier. | |
[ 51] func NameString(s string) string { | |
[ 52] return ((*Name)(&s)).String() | |
[ 53] } | |
[ 54] | |
[ 55] // ErrNameString escapes an identifier stored a string to a SQL | |
[ 56] // identifier suitable for printing in error messages, avoiding a heap | |
[ 57] // allocation. | |
[ 58] func ErrNameString(s *string) string { | |
[ 59] return ErrString(((*Name)(s))) | |
[ 60] } | |
[ 61] | |
[ 62] // Normalize normalizes to lowercase and Unicode Normalization Form C | |
[ 63] // (NFC). | |
[ 64] func (n Name) Normalize() string { | |
[ 65] return lex.NormalizeName(string(n)) | |
[ 66] } | |
[ 67] | |
[ 68] // An UnrestrictedName is a Name that does not need to be escaped when it | |
[ 69] // matches a reserved keyword. | |
[ 70] // | |
[ 71] // In general, an UnrestrictedName is the result of parsing an unrestricted_name | |
[ 72] // nonterminal, which is used in the grammar where reserved keywords can be | |
[ 73] // unambiguously interpreted as identifiers. When formatted, an UnrestrictedName | |
[ 74] // that matches a reserved keyword thus does not need to be quoted. | |
[ 75] // | |
[ 76] // For historical reasons, some unrestricted_name nonterminals are instead | |
[ 77] // parsed as Names. The only user-visible impact of this is that we are too | |
[ 78] // aggressive about quoting names in certain positions. New grammar rules should | |
[ 79] // prefer to parse unrestricted_name nonterminals into UnrestrictedNames. | |
[ 80] type UnrestrictedName string | |
[ 81] | |
[ 82] // Format implements the NodeFormatter interface. | |
[ 83] func (u *UnrestrictedName) Format(ctx *FmtCtx) { | |
[ 84] f := ctx.flags | |
[ 85] if f.HasFlags(FmtAnonymize) { | |
[ 86] ctx.WriteByte('_') | |
[ 87] } else { | |
[ 88] lex.EncodeUnrestrictedSQLIdent(ctx.Buffer, string(*u), f.EncodeFlags()) | |
[ 89] } | |
[ 90] } | |
[ 91] | |
[ 92] // ToStrings converts the name list to an array of regular strings. | |
[ 93] func (l NameList) ToStrings() []string { | |
[ 94] if l == nil { | |
[ 95] return nil | |
[ 96] } | |
[ 97] names := make([]string, len(l)) | |
[ 98] for i, n := range l { | |
[ 99] names[i] = string(n) | |
[ 100] } | |
[ 101] return names | |
[ 102] } | |
[ 103] | |
[ 104] // A NameList is a list of identifiers. | |
[ 105] type NameList []Name | |
[ 106] | |
[ 107] // Format implements the NodeFormatter interface. | |
[ 108] func (l *NameList) Format(ctx *FmtCtx) { | |
[ 109] for i := range *l { | |
[ 110] if i > 0 { | |
[ 111] ctx.WriteString(", ") | |
[ 112] } | |
[ 113] ctx.FormatNode(&(*l)[i]) | |
[ 114] } | |
[ 115] } | |
[ 116] | |
[ 117] // ArraySubscript corresponds to the syntax `<name>[ ... ]`. | |
[ 118] type ArraySubscript struct { | |
[ 119] Begin Expr | |
[ 120] End Expr | |
[ 121] Slice bool | |
[ 122] } | |
[ 123] | |
[ 124] // Format implements the NodeFormatter interface. | |
[ 125] func (a *ArraySubscript) Format(ctx *FmtCtx) { | |
[ 126] ctx.WriteByte('[') | |
[ 127] if a.Begin != nil { | |
[ 128] ctx.FormatNode(a.Begin) | |
[ 129] } | |
[ 130] if a.Slice { | |
[ 131] ctx.WriteByte(':') | |
[ 132] if a.End != nil { | |
[ 133] ctx.FormatNode(a.End) | |
[ 134] } | |
[ 135] } | |
[ 136] ctx.WriteByte(']') | |
[ 137] } | |
[ 138] | |
[ 139] // UnresolvedName corresponds to an unresolved qualified name. | |
[ 140] type UnresolvedName struct { | |
[ 141] // NumParts indicates the number of name parts specified, including | |
[ 142] // the star. Always 1 or greater. | |
[ 143] NumParts int | |
[ 144] | |
[ 145] // Star indicates the name ends with a star. | |
[ 146] // In that case, Parts below is empty in the first position. | |
[ 147] Star bool | |
[ 148] | |
[ 149] // Parts are the name components, in reverse order. | |
[ 150] // There are at most 4: column, table, schema, catalog/db. | |
[ 151] // | |
[ 152] // Note: NameParts has a fixed size so that we avoid a heap | |
[ 153] // allocation for the slice every time we construct an | |
[ 154] // UnresolvedName. It does imply however that Parts does not have | |
[ 155] // a meaningful "length"; its actual length (the number of parts | |
[ 156] // specified) is populated in NumParts above. | |
[ 157] Parts NameParts | |
[ 158] } | |
[ 159] | |
[ 160] // NameParts is the array of strings that composes the path in an | |
[ 161] // UnresolvedName. | |
[ 162] type NameParts = [4]string | |
[ 163] | |
[ 164] // Format implements the NodeFormatter interface. | |
[ 165] func (u *UnresolvedName) Format(ctx *FmtCtx) { | |
[ 166] stopAt := 1 | |
[ 167] if u.Star { | |
[ 168] stopAt = 2 | |
[ 169] } | |
[ 170] // Every part after that is necessarily an unrestricted name. | |
[ 171] for i := u.NumParts; i >= stopAt; i-- { | |
[ 172] // The first part to print is the last item in u.Parts. It is also | |
[ 173] // a potentially restricted name to disambiguate from keywords in | |
[ 174] // the grammar, so print it out as a "Name". | |
[ 175] if i == u.NumParts { | |
[ 176] ctx.FormatNode((*Name)(&u.Parts[i-1])) | |
[ 177] } else { | |
[ 178] ctx.FormatNode((*UnrestrictedName)(&u.Parts[i-1])) | |
[ 179] } | |
[ 180] if i > 1 { | |
[ 181] ctx.WriteByte('.') | |
[ 182] } | |
[ 183] } | |
[ 184] if u.Star { | |
[ 185] ctx.WriteByte('*') | |
[ 186] } | |
[ 187] } | |
[ 188] func (u *UnresolvedName) String() string { return AsString(u) } | |
[ 189] | |
[ 190] // NewUnresolvedName constructs an UnresolvedName from some strings. | |
[ 191] func NewUnresolvedName(args ...string) *UnresolvedName { | |
[ 192] n := &UnresolvedName{NumParts: len(args)} | |
[ 193] for i := 0; i < len(args); i++ { | |
[ 194] n.Parts[i] = args[len(args)-1-i] | |
[ 195] } | |
[ 196] return n | |
[ 197] } | |
[INFO][00:17:57] Applied 'ShowPatchAction' on 'pkg/sql/sem/tree/name_part.go' from 'GofmtBear'. | |
[WARNING][00:17:57] GoVetBear: This result has no patch attached. | |
pkg/sql/sem/tree/name_part.go | |
[ 16] | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! expected type, found '=' (and 1 more errors) | |
**** GofmtBear [Section <empty> | Severity NORMAL] **** | |
! ! Formatting can be improved. | |
[----] /home/palash25/Dev/cockroach/pkg/sql/schema_accessors.go | |
[++++] /home/palash25/Dev/cockroach/pkg/sql/schema_accessors.go | |
[ 1] // Copyright 2018 The Cockroach Authors. | |
[ 2] // | |
[ 3] // Licensed under the Apache License, Version 2.0 (the "License"); | |
[ 4] // you may not use this file except in compliance with the License. | |
[ 5] // You may obtain a copy of the License at | |
[ 6] // | |
[ 7] // http://www.apache.org/licenses/LICENSE-2.0 | |
[ 8] // | |
[ 9] // Unless required by applicable law or agreed to in writing, software | |
[ 10] // distributed under the License is distributed on an "AS IS" BASIS, | |
[ 11] // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
[ 12] // implied. See the License for the specific language governing | |
[ 13] // permissions and limitations under the License. | |
[ 14] | |
[ 15] package sql | |
[ 16] | |
[ 17] import ( | |
[ 18] "context" | |
[ 19] | |
[ 20] "github.com/cockroachdb/cockroach/pkg/internal/client" | |
[ 21] "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" | |
[ 22] "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" | |
[ 23] ) | |
[ 24] | |
[ 25] // This file provides high-level interfaces to abstract access to the | |
[ 26] // SQL schema (the descriptors). | |
[ 27] // | |
[ 28] // The following interfaces are defined: | |
[ 29] // - DatabaseAccessor, which provides access to database descriptors. | |
[ 30] // - DatabaseLister, which provides a service to list the contents of a database. | |
[ 31] // - ObjectAccessor, which provides access to individual object descriptors. | |
[ 32] // | |
[ 33] // A common interface SchemaAccessor is provided for convenience. | |
[ 34] // | |
[ 35] // See physical_schema_accessors.go and logical_schema_accessors.go for | |
[ 36] // reference implementations of these interfaces. | |
[ 37] | |
[ 38] type ( | |
[ 39] // ObjectName is provided for convenience and to make the interface | |
[ 40] // definitions below more intuitive. | |
[ 41] ObjectName = tree.TableName | |
[ 42] // DatabaseDescriptor is provided for convenience and to make the | |
[ 43] // interface definitions below more intuitive. | |
[ 44] DatabaseDescriptor = sqlbase.DatabaseDescriptor | |
[ 45] // ObjectDescriptor is provided for convenience and to make the | |
[ 46] // interface definitions below more intuitive. | |
[ 47] ObjectDescriptor = sqlbase.TableDescriptor | |
[ 48] // TableDescriptor is provided for convenience and to make the | |
[ 49] // interface definitions below more intuitive. | |
[ 50] TableDescriptor = sqlbase.TableDescriptor | |
[ 51] // ViewDescriptor is provided for convenience and to make the | |
[ 52] // interface definitions below more intuitive. | |
[ 53] ViewDescriptor = sqlbase.TableDescriptor | |
[ 54] // SequenceDescriptor is provided for convenience and to make the | |
[ 55] // interface definitions below more intuitive. | |
[ 56] SequenceDescriptor = sqlbase.TableDescriptor | |
[ 57] // TableNames is provided for convenience and to make the interface | |
[ 58] // definitions below more intuitive. | |
[ 59] TableNames = tree.TableNames | |
[ 60] ) | |
[ 61] | |
[ 62] // SchemaAccessor provides access to database descriptors. | |
[ 63] type SchemaAccessor interface { | |
[ 64] // GetDatabaseDesc looks up a database by name and returns its | |
[ 65] // descriptor. If the database is not found and required is true, | |
[ 66] // an error is returned; otherwise a nil reference is returned. | |
[ 67] GetDatabaseDesc(dbName string, flags DatabaseLookupFlags) (*DatabaseDescriptor, error) | |
[ 68] | |
[ 69] // IsValidSchema returns true if the given schema name is valid for the given database. | |
[ 70] IsValidSchema(db *DatabaseDescriptor, scName string) bool | |
[ 71] | |
[ 72] // GetObjectNames returns the list of all objects in the given | |
[ 73] // database and schema. | |
[ 74] // TODO(whomever): when separate schemas are supported, this | |
[ 75] // API should be extended to use schema descriptors. | |
[ 76] GetObjectNames(db *DatabaseDescriptor, scName string, flags DatabaseListFlags) (TableNames, error) | |
[ 77] | |
[ 78] // GetObjectDesc looks up an objcet by name and returns both its | |
[ 79] // descriptor and that of its parent database. If the object is not | |
[ 80] // found and flags.required is true, an error is returned, otherwise | |
[ 81] // a nil reference is returned. | |
[ 82] // | |
[ 83] // flag.allowAdding controls inclusion of non-public descriptors. | |
[ 84] // | |
[ 85] // The 2nd return value (DatabaseDescriptor) is only returned if the | |
[ 86] // lookup function otherwise needed to load the database descriptor. | |
[ 87] // It is not guaranteed to be non-nil even if the first return value | |
[ 88] // is non-nil. Callers that need a database descriptor can use that | |
[ 89] // to avoid an extra roundtrip through a DatabaseAccessor. | |
[ 90] GetObjectDesc(name *ObjectName, flags ObjectLookupFlags) (*ObjectDescriptor, *DatabaseDescriptor, error) | |
[ 91] } | |
[ 92] | |
[ 93] // CommonLookupFlags is the common set of flags for the various accessor interfaces. | |
[ 94] type CommonLookupFlags struct { | |
[ 95] ctx context.Context | |
[ 96] txn *client.Txn | |
[ 97] // if required is set, lookup will return an error if the item is not found. | |
[ 98] required bool | |
[ 99] // if avoidCached is set, lookup will avoid the cache (if any). | |
[ 100] avoidCached bool | |
[ 101] } | |
[ 102] | |
[ 103] // DatabaseLookupFlags is the flag struct suitable for GetDatabaseDesc(). | |
[ 104] type DatabaseLookupFlags = CommonLookupFlags | |
[ 105] | |
[ 106] // DatabaseListFlags is the flag struct suitable for GetObjectNames(). | |
[ 107] type DatabaseListFlags struct { | |
[ 108] CommonLookupFlags | |
[ 109] // explicitPrefix, when set, will cause the returned table names to | |
[ 110] // have an explicit schema and catalog part. | |
[ 111] explicitPrefix bool | |
[ 112] } | |
[ 113] | |
[ 114] // ObjectLookupFlags is the flag struct suitable for GetObjectDesc(). | |
[ 115] type ObjectLookupFlags struct { | |
[ 116] CommonLookupFlags | |
[ 117] // if allowAdding is set, descriptors in the ADD state will be | |
[ 118] // included in the results as well. | |
[ 119] allowAdding bool | |
[ 120] } | |
[INFO][00:17:58] Applied 'ShowPatchAction' on 'pkg/sql/schema_accessors.go' from 'GofmtBear'. | |
[WARNING][00:17:58] GoVetBear: This result has no patch attached. | |
pkg/sql/schema_accessors.go | |
[ 13] //·permissions·and·limitations·under·the·License. | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! expected type, found '=' (and 6 more errors) | |
[WARNING][00:17:59] GoVetBear: This result has no patch attached. | |
pkg/sql/show_stats.go | |
[ 128] » » » » res·:=·tree.Datums{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
[WARNING][00:17:59] GoVetBear: This result has no patch attached. | |
pkg/sql/show_constraints.go | |
[ 101] » » » » ordering:·sqlbase.ColumnOrdering{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ColumnOrdering composite literal uses unkeyed fields | |
[WARNING][00:18:01] GoVetBear: This result has no patch attached. | |
pkg/storage/replica.go | |
[4215] » » » » » fmt.Sprintf("unknown·status·for·command·without·MaxLeaseIndex·"+ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg reason for printf verb %s of wrong type: storage.refreshRaftReason | |
[WARNING][00:18:01] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:01] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:01] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:01] GoVetBear: This result has no patch attached. | |
pkg/sql/sqlbase/privilege_test.go | |
[ 382] » » » » security.RootUser:·privilege.List{privilege.ALL}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! privilege.List composite literal uses unkeyed fields | |
pkg/sql/sqlbase/privilege_test.go | |
[ 383] » » » » AdminRole:·········privilege.List{privilege.ALL}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! privilege.List composite literal uses unkeyed fields | |
pkg/sql/sqlbase/privilege_test.go | |
[ 433] » » » » security.RootUser:·privilege.List{privilege.ALL}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! privilege.List composite literal uses unkeyed fields | |
pkg/sql/sqlbase/privilege_test.go | |
[ 434] » » » » AdminRole:·········privilege.List{privilege.ALL}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! privilege.List composite literal uses unkeyed fields | |
[WARNING][00:18:03] GoVetBear: This result has no patch attached. | |
pkg/sql/opt/optbuilder/scope.go | |
[ 468] » » » » » » » NumParts:·1,·Parts:·tree.NameParts{"count_rows"}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.NameParts composite literal uses unkeyed fields | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:04] GoVetBear: This result has no patch attached. | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 37] » » Start:·LogicalKey{Vals:·tree.Datums{value},·Inclusive:·true}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 38] » » End:···LogicalKey{Vals:·tree.Datums{value},·Inclusive:·true}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 51] » » sp.Start·=·LogicalKey{Vals:·tree.Datums{tree.DNull},·Inclusive:·false} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 53] » » sp.End·=·LogicalKey{Vals:·tree.Datums{tree.DNull},·Inclusive:·false} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 63] » startKey·:=·LogicalKey{Vals:·tree.Datums{tree.NewDString(prefix)},·Inclusive:·true} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 85] » endKey·:=·LogicalKey{Vals:·tree.Datums{endDatum},·Inclusive:·false} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 184] » » » sp.End·=·LogicalKey{Vals:·tree.Datums{datum},·Inclusive:·inclusive} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 186] » » » sp.Start·=·LogicalKey{Vals:·tree.Datums{datum},·Inclusive:·inclusive} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 195] » » spans[0].End·=·LogicalKey{Vals:·tree.Datums{datum},·Inclusive:·false} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 196] » » spans[1].Start·=·LogicalKey{Vals:·tree.Datums{datum},·Inclusive:·false} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 894] » » » spans[0].Start·=·LogicalKey{Vals:·tree.Datums{rightDatum},·Inclusive:·true} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
pkg/sql/opt/idxconstraint/index_constraints.go | |
[ 898] » » » spans[1].Start·=·LogicalKey{Vals:·tree.Datums{dJSON},·Inclusive:·true} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
[WARNING][00:18:05] GoVetBear: This result has no patch attached. | |
pkg/base/config.go | |
[ 168] » cfg.certificateManager·=·lazyCertificateManager{} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! assignment copies lock value to cfg.certificateManager: base.lazyCertificateManager contains sync.Once contains sync.Mutex | |
[WARNING][00:18:08] GoVetBear: This result has no patch attached. | |
pkg/sql/value_generator.go | |
[ 75] » » columns:··········sqlbase.ResultColumns{{Name:·t.Func.String(),·Typ:·normalized.ResolvedType()}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.ResultColumns composite literal uses unkeyed fields | |
[WARNING][00:18:09] GoVetBear: This result has no patch attached. | |
pkg/sql/pg_catalog.go | |
[1223] » return·&tree.DArray{ParamTyp:·types.String,·Array:·tree.Datums{tree.NewDString(s)}} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.Datums composite literal uses unkeyed fields | |
**** GofmtBear [Section <empty> | Severity NORMAL] **** | |
! ! Formatting can be improved. | |
[----] /home/palash25/Dev/cockroach/pkg/sql/opt/metadata_column.go | |
[++++] /home/palash25/Dev/cockroach/pkg/sql/opt/metadata_column.go | |
[ 1] // Copyright 2018 The Cockroach Authors. | |
[ 2] // | |
[ 3] // Licensed under the Apache License, Version 2.0 (the "License"); | |
[ 4] // you may not use this file except in compliance with the License. | |
[ 5] // You may obtain a copy of the License at | |
[ 6] // | |
[ 7] // http://www.apache.org/licenses/LICENSE-2.0 | |
[ 8] // | |
[ 9] // Unless required by applicable law or agreed to in writing, software | |
[ 10] // distributed under the License is distributed on an "AS IS" BASIS, | |
[ 11] // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
[ 12] // implied. See the License for the specific language governing | |
[ 13] // permissions and limitations under the License. | |
[ 14] | |
[ 15] package opt | |
[ 16] | |
[ 17] import ( | |
[ 18] "github.com/cockroachdb/cockroach/pkg/util" | |
[ 19] ) | |
[ 20] | |
[ 21] // ColumnID uniquely identifies the usage of a column within the scope of a | |
[ 22] // query. ColumnID 0 is reserved to mean "unknown column". See the comment for | |
[ 23] // Metadata for more details. | |
[ 24] type ColumnID int32 | |
[ 25] | |
[ 26] // ColSet efficiently stores an unordered set of column ids. | |
[ 27] type ColSet = util.FastIntSet | |
[ 28] | |
[ 29] // ColList is a list of column ids. | |
[ 30] // | |
[ 31] // TODO(radu): perhaps implement a FastIntList with the same "small" | |
[ 32] // representation as FastIntMap but with a slice for large cases. | |
[ 33] type ColList = []ColumnID | |
[ 34] | |
[ 35] // ColMap provides a 1:1 mapping from one column id to another. It is used by | |
[ 36] // operators that need to match columns from its inputs. | |
[ 37] type ColMap = util.FastIntMap | |
[ 38] | |
[ 39] // LabeledColumn specifies the label and id of a column. | |
[ 40] type LabeledColumn struct { | |
[ 41] Label string | |
[ 42] ID ColumnID | |
[ 43] } | |
[ 44] | |
[ 45] // OrderingColumn is the ColumnID for a column that is part of an ordering, | |
[ 46] // except that it can be negated to indicate a descending ordering on that | |
[ 47] // column. | |
[ 48] type OrderingColumn int32 | |
[ 49] | |
[ 50] // MakeOrderingColumn initializes an ordering column with a ColumnID and a flag | |
[ 51] // indicating whether the direction is descending. | |
[ 52] func MakeOrderingColumn(id ColumnID, descending bool) OrderingColumn { | |
[ 53] if descending { | |
[ 54] return OrderingColumn(-id) | |
[ 55] } | |
[ 56] return OrderingColumn(id) | |
[ 57] } | |
[ 58] | |
[ 59] // ID returns the ColumnID for this OrderingColumn. | |
[ 60] func (c OrderingColumn) ID() ColumnID { | |
[ 61] if c < 0 { | |
[ 62] return ColumnID(-c) | |
[ 63] } | |
[ 64] return ColumnID(c) | |
[ 65] } | |
[ 66] | |
[ 67] // Ascending returns true if the ordering on this column is ascending. | |
[ 68] func (c OrderingColumn) Ascending() bool { | |
[ 69] return c > 0 | |
[ 70] } | |
[ 71] | |
[ 72] // Descending returns true if the ordering on this column is descending. | |
[ 73] func (c OrderingColumn) Descending() bool { | |
[ 74] return c < 0 | |
[ 75] } | |
[ 76] | |
[ 77] // ColListToSet converts a column id list to a column id set. | |
[ 78] func ColListToSet(colList ColList) ColSet { | |
[ 79] var r ColSet | |
[ 80] for _, col := range colList { | |
[ 81] r.Add(int(col)) | |
[ 82] } | |
[ 83] return r | |
[ 84] } | |
[INFO][00:18:10] Applied 'ShowPatchAction' on 'pkg/sql/opt/metadata_column.go' from 'GofmtBear'. | |
[WARNING][00:18:10] GoVetBear: This result has no patch attached. | |
pkg/sql/opt/metadata_column.go | |
[ 13] //·permissions·and·limitations·under·the·License. | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! expected type, found '=' (and 2 more errors) | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:11] GoVetBear: This result has no patch attached. | |
pkg/sql/sem/builtins/builtins.go | |
[ 215] » » » Types:······tree.ArgTypes{{"val",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 232] » » » Types:······tree.ArgTypes{{"val",·types.Bytes}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 263] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 277] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 291] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 307] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 324] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 338] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 351] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 365] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 387] » » » Types:······tree.ArgTypes{{"val",·types.INet}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 404] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 420] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 437] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 454] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 471] » » » Types:······tree.ArgTypes{{"val",·types.Bytes}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 490] » » » Types:······tree.ArgTypes{{"val",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 510] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 540] » » » Types:············tree.ArgTypes{{"input",·types.String},·{"repeat_counter",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 572] » » » Types:······tree.ArgTypes{{"data",·types.Bytes},·{"format",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 593] » » » Types:······tree.ArgTypes{{"text",·types.String},·{"format",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 677] » » » Types:······tree.ArgTypes{{"val",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 685] » » » Types:······tree.ArgTypes{{"val",·types.Bytes}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 708] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 726] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 840] » » » Types:······tree.ArgTypes{{"input",·types.String},·{"regex",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 853] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 876] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 929] » » » Types:······tree.ArgTypes{{"input",·types.Bytes},·{"return_set",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 947] » » » Types:······tree.ArgTypes{{"input",·types.String},·{"return_set",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 968] » » » Types:······tree.ArgTypes{{"input",·types.Bytes},·{"return_set",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[ 986] » » » Types:······tree.ArgTypes{{"input",·types.String},·{"return_set",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1038] » » » Types:······tree.ArgTypes{{"sequence_name",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1060] » » » Types:······tree.ArgTypes{{"sequence_name",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1101] » » » Types:······tree.ArgTypes{{"sequence_name",·types.String},·{"value",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1123] » » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1182] » » » Types:······tree.ArgTypes{{"input",·types.Timestamp},·{"extract_format",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1198] » » » Types:······tree.ArgTypes{{"input",·types.Date},·{"extract_format",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1214] » » » Types:······tree.ArgTypes{{"input",·types.TimestampTZ},·{"extract_format",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1233] » » » Types:······tree.ArgTypes{{"input",·types.String},·{"format",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1252] » » » Types:······tree.ArgTypes{{"val",·types.TimestampTZ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1260] » » » Types:······tree.ArgTypes{{"begin",·types.TimestampTZ},·{"end",·types.TimestampTZ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1344] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.Timestamp}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1358] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.Date}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1372] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.TimestampTZ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1385] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.Time}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1400] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.Interval}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1471] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.Timestamp}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1489] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.Date}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1504] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.Time}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1521] » » » Types:······tree.ArgTypes{{"element",·types.String},·{"input",·types.TimestampTZ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1547] » » » Types:······tree.ArgTypes{{"val",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1632] » » » Types:······tree.ArgTypes{{"x",·types.Int},·{"y",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1672] » » » Types:······tree.ArgTypes{{"val",·types.Float}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1680] » » » Types:······tree.ArgTypes{{"val",·types.Decimal}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1692] » » » Types:······tree.ArgTypes{{"val",·types.JSON},·{"path",·types.TArray{Typ:·types.String}}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1716] » » » Types:······tree.ArgTypes{{"val",·types.JSON}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1784] » » » Types:······tree.ArgTypes{{"x",·types.Int},·{"y",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1827] » » » Types:······tree.ArgTypes{{"input",·types.Float},·{"decimal_accuracy",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1858] » » » Types:······tree.ArgTypes{{"input",·types.Decimal},·{"decimal_accuracy",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1895] » » » Types:······tree.ArgTypes{{"val",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1949] » » » Types:······tree.ArgTypes{{"val",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1981] » » » Types:········tree.ArgTypes{{"str",·types.String},·{"delimiter",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[1996] » » » Types:········tree.ArgTypes{{"str",·types.String},·{"delimiter",·types.String},·{"null",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2015] » » » Types:······tree.ArgTypes{{"input",·types.AnyArray},·{"array_dimension",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2031] » » » Types:······tree.ArgTypes{{"input",·types.AnyArray},·{"array_dimension",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2047] » » » Types:······tree.ArgTypes{{"input",·types.AnyArray},·{"array_dimension",·types.Int}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2063] » » » Types:········tree.ArgTypes{{"array",·types.TArray{Typ:·typ}},·{"elem",·typ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2076] » » » Types:········tree.ArgTypes{{"elem",·typ},·{"array",·types.TArray{Typ:·typ}}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2089] » » » Types:········tree.ArgTypes{{"left",·types.TArray{Typ:·typ}},·{"right",·types.TArray{Typ:·typ}}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2102] » » » Types:········tree.ArgTypes{{"array",·types.TArray{Typ:·typ}},·{"elem",·typ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2126] » » » Types:········tree.ArgTypes{{"array",·types.TArray{Typ:·typ}},·{"toreplace",·typ},·{"replacewith",·typ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2154] » » » Types:········tree.ArgTypes{{"array",·types.TArray{Typ:·typ}},·{"elem",·typ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2175] » » » Types:········tree.ArgTypes{{"array",·types.TArray{Typ:·typ}},·{"elem",·typ}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2249] » » » Types:······tree.ArgTypes{{"include_pg_catalog",·types.Bool}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2321] » » » Types:······tree.ArgTypes{{"errorCode",·types.String},·{"msg",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2339] » » » Types:······tree.ArgTypes{{"msg",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2354] » » » Types:······tree.ArgTypes{{"msg",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2375] » » » Types:······tree.ArgTypes{{"val",·types.Interval}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2397] » » » Types:······tree.ArgTypes{{"input",·types.Any}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2410] » » » Types:······tree.ArgTypes{{"vmodule_string",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2426] » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2447] » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2485] » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2498] » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2569] » » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2632] » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2650] » Types:·tree.ArgTypes{ | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2671] » Types:······tree.ArgTypes{{"val",·types.JSON}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2730] » Types:······tree.ArgTypes{{"val",·types.Any}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2762] » » Types:······tree.ArgTypes{{"texts",·types.TArray{Typ:·types.String}}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2791] » » Types:·tree.ArgTypes{{"keys",·types.TArray{Typ:·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2824] » Types:······tree.ArgTypes{{"from_json",·types.JSON}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2834] » Types:······tree.ArgTypes{{"json",·types.JSON}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2881] » » Types:······tree.ArgTypes{{"val",·types.Float}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2894] » » Types:······tree.ArgTypes{{a,·types.Float},·{b,·types.Float}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2906] » » Types:······tree.ArgTypes{{"val",·types.Decimal}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2920] » » Types:······tree.ArgTypes{{a,·types.Decimal},·{b,·types.Decimal}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2935] » » Types:······tree.ArgTypes{{"val",·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2951] » » Types:······tree.ArgTypes{{a,·types.String},·{b,·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2968] » » Types:······tree.ArgTypes{{a,·types.String},·{b,·types.String},·{c,·types.String}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
pkg/sql/sem/builtins/builtins.go | |
[2981] » » Types:······tree.ArgTypes{{"val",·types.Bytes}}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.ArgTypes composite literal uses unkeyed fields | |
[WARNING][00:18:13] GoVetBear: This result has no patch attached. | |
pkg/sql/parser/help.go | |
[ 138] » un·:=·&tree.UnresolvedName{NumParts:·1,·Parts:·tree.NameParts{s}} | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! tree.NameParts composite literal uses unkeyed fields | |
[WARNING][00:18:16] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:16] GoVetBear: This result has no patch attached. | |
pkg/sql/opt_exec_engine.go | |
[ 198] » » sourceInfo:·sqlbase.MultiSourceInfo{src.info}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.MultiSourceInfo composite literal uses unkeyed fields | |
pkg/sql/opt_exec_engine.go | |
[ 223] » » sourceInfo:·sqlbase.MultiSourceInfo{src.info}, | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! sqlbase.MultiSourceInfo composite literal uses unkeyed fields | |
[WARNING][00:18:17] GoVetBear: This result has no patch attached. | |
[WARNING][00:18:17] GoVetBear: This result has no patch attached. | |
pkg/sql/pgwire/pgwirebase/encoding.go | |
[ 506] » » return·nil,·errors.Errorf("unsupported·format·code:·%s",·code) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg code for printf verb %s of wrong type: pgwirebase.FormatCode | |
pkg/sql/pgwire/pgwirebase/encoding.go | |
[ 522] » » return·nil,·errors.Errorf("unsupported·OID·%v·with·format·code·%s",·id,·code) | |
**** GoVetBear [Section: all.go | Severity: NORMAL] **** | |
! ! arg code for printf verb %s of wrong type: pgwirebase.FormatCode | |
Executing section cli... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment