github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/builtin_test.go (about) 1 // Copyright 2018 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sql 12 13 import ( 14 "context" 15 "fmt" 16 "strings" 17 "testing" 18 19 "github.com/cockroachdb/cockroach/pkg/base" 20 "github.com/cockroachdb/cockroach/pkg/sql/sem/builtins" 21 "github.com/cockroachdb/cockroach/pkg/sql/types" 22 "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" 23 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 24 ) 25 26 // TestFuncNull execs all builtin funcs with various kinds of NULLs, 27 // attempting to induce a panic. 28 func TestFuncNull(t *testing.T) { 29 defer leaktest.AfterTest(t)() 30 31 s, db, _ := serverutils.StartServer(t, base.TestServerArgs{}) 32 ctx := context.Background() 33 defer s.Stopper().Stop(ctx) 34 35 run := func(t *testing.T, q string) { 36 rows, err := db.QueryContext(ctx, q) 37 if err == nil { 38 rows.Close() 39 } 40 } 41 42 for _, name := range builtins.AllBuiltinNames { 43 switch strings.ToLower(name) { 44 case "crdb_internal.force_panic", "crdb_internal.force_log_fatal", "pg_sleep": 45 continue 46 } 47 _, variations := builtins.GetBuiltinProperties(name) 48 for _, builtin := range variations { 49 // Untyped NULL. 50 { 51 var sb strings.Builder 52 fmt.Fprintf(&sb, "SELECT %s(", name) 53 for i := range builtin.Types.Types() { 54 if i > 0 { 55 sb.WriteString(", ") 56 } 57 sb.WriteString("NULL") 58 } 59 sb.WriteString(")") 60 run(t, sb.String()) 61 } 62 // Typed NULL. 63 { 64 var sb strings.Builder 65 fmt.Fprintf(&sb, "SELECT %s(", name) 66 for i, typ := range builtin.Types.Types() { 67 if i > 0 { 68 sb.WriteString(", ") 69 } 70 fmt.Fprintf(&sb, "NULL::%s", typ) 71 } 72 sb.WriteString(")") 73 run(t, sb.String()) 74 } 75 // NULL that the type system can't (at least not yet?) know is NULL. 76 { 77 var sb strings.Builder 78 fmt.Fprintf(&sb, "SELECT %s(", name) 79 for i, typ := range builtin.Types.Types() { 80 if i > 0 { 81 sb.WriteString(", ") 82 } 83 fmt.Fprintf(&sb, "(SELECT NULL)::%s", typ) 84 } 85 sb.WriteString(")") 86 run(t, sb.String()) 87 } 88 // For array types, make an array with a NULL. 89 { 90 var sb strings.Builder 91 fmt.Fprintf(&sb, "SELECT %s(", name) 92 hasArray := false 93 for i, typ := range builtin.Types.Types() { 94 if i > 0 { 95 sb.WriteString(", ") 96 } 97 if typ.Family() == types.ArrayFamily { 98 hasArray = true 99 if typ.ArrayContents().Family() == types.AnyFamily { 100 fmt.Fprintf(&sb, "ARRAY[NULL]::STRING[]") 101 } else { 102 fmt.Fprintf(&sb, "ARRAY[NULL]::%s", typ) 103 } 104 } else { 105 fmt.Fprintf(&sb, "NULL::%s", typ) 106 } 107 } 108 if hasArray { 109 sb.WriteString(")") 110 run(t, sb.String()) 111 } 112 } 113 } 114 } 115 }