Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
110774: pgcryptocipherccl: convert invariant errors into assertions r=rafiss a=andyyang890

This patch changes the checks for programmer error in the `pgcryptocipherccl` package to use `errors.AssertionFailedf` so that they are surfaced with greater visibility.

Epic: None

Release note: None

110803: rangefeed: actually use scheduler in scheduler benchmarks r=erikgrinaker a=erikgrinaker

Epic: none
Release note: None

110829: testing: set UseTransactionalDescIDGenerator testing knob in SQLTranslator tests r=rafiss a=ecwall

Fixes #110242
Fixes #110240

Set UseTransactionalDescIDGenerator to true to prevent transaction retries from
resulting in different descriptor IDs. Descriptor IDs appear directly in the test
output and must remain stable.

Release note: None

110830: storage: ignore {exclusive,shared} locks in ScanConflictingIntentsForDroppingLatchesEarly r=nvanbenschoten a=arulajmani

ScanConflictingIntentsForDroppingLatchesEarly is called by non-locking read requests to check for conflicts before evaluating. Non-locking reads do not conflict with Exclusive or Shared locks -- so these can be ignored when scanning the lock table. This patch does so, by making use of an appropriately configured `LockTableIterator`.

Informs #100193

Release note: None

Co-authored-by: Andy Yang <[email protected]>
Co-authored-by: Erik Grinaker <[email protected]>
Co-authored-by: Evan Wall <[email protected]>
Co-authored-by: Arul Ajmani <[email protected]>
  • Loading branch information
5 people committed Sep 18, 2023
5 parents 0fbda83 + 0e38f38 + 3899e67 + b232ffe + 0c9bbb4 commit 0b2ced7
Show file tree
Hide file tree
Showing 31 changed files with 268 additions and 213 deletions.
10 changes: 5 additions & 5 deletions pkg/ccl/pgcryptoccl/pgcryptocipherccl/cipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func newCipher(method cipherMethod, key []byte) (cipher.Block, error) {
}
return aes.NewCipher(key)
default:
return nil, errors.Newf("cannot create new cipher for unknown algorithm: %d", a)
return nil, errors.AssertionFailedf("cannot create new cipher for unknown algorithm: %d", a)
}
}

Expand All @@ -99,7 +99,7 @@ func padData(method cipherMethod, data []byte, blockSize int) ([]byte, error) {
case noPadding:
return data, nil
default:
return nil, errors.Newf("cannot pad for unknown padding: %d", p)
return nil, errors.AssertionFailedf("cannot pad for unknown padding: %d", p)
}
}

Expand All @@ -110,7 +110,7 @@ func unpadData(method cipherMethod, data []byte) ([]byte, error) {
case noPadding:
return data, nil
default:
return nil, errors.Newf("cannot unpad for unknown padding: %d", p)
return nil, errors.AssertionFailedf("cannot unpad for unknown padding: %d", p)
}
}

Expand Down Expand Up @@ -138,7 +138,7 @@ func encrypt(method cipherMethod, block cipher.Block, iv []byte, data []byte) ([
mode.CryptBlocks(ret, data)
return ret, nil
default:
return nil, errors.Newf("cannot encrypt for unknown mode: %d", m)
return nil, errors.AssertionFailedf("cannot encrypt for unknown mode: %d", m)
}
}

Expand All @@ -155,6 +155,6 @@ func decrypt(method cipherMethod, block cipher.Block, iv []byte, data []byte) ([
mode.CryptBlocks(ret, data)
return ret, nil
default:
return nil, errors.Newf("cannot encrypt for unknown mode: %d", m)
return nil, errors.AssertionFailedf("cannot decrypt for unknown mode: %d", m)
}
}
12 changes: 8 additions & 4 deletions pkg/ccl/pgcryptoccl/pgcryptocipherccl/padding.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"bytes"
"math"

"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
"github.com/cockroachdb/errors"
)

Expand All @@ -20,7 +22,7 @@ import (
// https://datatracker.ietf.org/doc/html/rfc5652#section-6.3.
func pkcsPad(data []byte, blockSize int) ([]byte, error) {
if blockSize <= 0 || blockSize > math.MaxUint8 {
return nil, errors.Newf("invalid block size for PKCS padding: %d", blockSize)
return nil, errors.AssertionFailedf("invalid block size for PKCS padding: %d", blockSize)
}

paddedData := make([]byte, len(data))
Expand All @@ -36,16 +38,18 @@ func pkcsPad(data []byte, blockSize int) ([]byte, error) {
// pkcsUnpad removes the padding added by pkcsPad.
func pkcsUnpad(data []byte) ([]byte, error) {
if len(data) == 0 {
return nil, errors.New("PKCS-padded data is empty")
return nil, pgerror.New(pgcode.InvalidParameterValue, "PKCS-padded data is empty")
}

paddingLen := data[len(data)-1]
if paddingLen == 0 || int(paddingLen) > len(data) {
return nil, errors.Newf("invalid final byte found in PKCS-padded data: %d", paddingLen)
return nil, pgerror.Newf(pgcode.InvalidParameterValue,
"invalid final byte found in PKCS-padded data: %d", paddingLen)
}
for i := 1; i < int(paddingLen); i++ {
if b := data[len(data)-i-1]; b != paddingLen {
return nil, errors.Newf("invalid byte found in PKCS-padded data: expected %d, but found %d", paddingLen, b)
return nil, pgerror.Newf(pgcode.InvalidParameterValue,
"invalid byte found in PKCS-padded data: expected %d, but found %d", paddingLen, b)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
"context"
"fmt"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"sync"
"testing"
Expand Down Expand Up @@ -44,8 +42,6 @@ import (
"github.com/stretchr/testify/require"
)

var tableIDPrefixRegexp = regexp.MustCompile("(/Table/)([0-9]+)(.*)")

// TestDataDriven is a data-driven test for the spanconfig.SQLTranslator. It
// allows users to set up zone config hierarchies and validate their translation
// to SpanConfigs is as expected. Only fields that are different from the
Expand Down Expand Up @@ -115,21 +111,24 @@ func TestDataDriven(t *testing.T) {
// test cluster).
ManagerDisableJobCreation: true,
}
sqlExecutorKnobs := &sql.ExecutorTestingKnobs{
UseTransactionalDescIDGenerator: true,
}
tsArgs := func(attr string) base.TestServerArgs {
return base.TestServerArgs{
Knobs: base.TestingKnobs{
GCJob: gcTestingKnobs,
SpanConfig: scKnobs,
GCJob: gcTestingKnobs,
SpanConfig: scKnobs,
SQLExecutor: sqlExecutorKnobs,
},
StoreSpecs: []base.StoreSpec{
{InMemory: true, Attributes: roachpb.Attributes{Attrs: []string{attr}}},
},
}
}
isMultiNode := strings.Contains(path, "3node")
// Use 1 node by default to make tests run faster.
nodes := 1
if isMultiNode {
if strings.Contains(path, "3node") {
nodes = 3
}
tc := testcluster.StartTestCluster(t, nodes, base.TestClusterArgs{
Expand Down Expand Up @@ -221,42 +220,7 @@ func TestDataDriven(t *testing.T) {
for _, record := range records {
switch {
case record.GetTarget().IsSpanTarget():
var translateOutputFmt, spanStr string
// The span's table ID may change in multi-node tests. Replace the
// table ID with <table-id> or <table-id+1> to make output
// deterministic.
if isMultiNode {
translateOutputFmt = "%-54s %s\n"
span := record.GetTarget().GetSpan()
parseKey := func(key roachpb.Key) (prefix string, tableID int, suffix string) {
keyStr := key.String()
matches := tableIDPrefixRegexp.FindStringSubmatch(keyStr)
require.Lenf(t, matches, 4, keyStr)
prefix = matches[1]
var err error
tableID, err = strconv.Atoi(matches[2])
require.NoErrorf(t, err, keyStr)
suffix = matches[3]
return
}
startPrefix, startTableID, startSuffix := parseKey(span.Key)
var tableIDPlaceholder = "<table-id>"
startKeyStr := fmt.Sprintf("%s%s%s", startPrefix, tableIDPlaceholder, startSuffix)
endPrefix, endTableID, endSuffix := parseKey(span.EndKey)
switch endTableID {
case startTableID:
case startTableID + 1:
tableIDPlaceholder = "<table-id+1>"
default:
t.Fatalf("invalid table IDs startTableID=%d endTableID=%d", startTableID, endTableID)
}
endKeyStr := fmt.Sprintf("%s%s%s", endPrefix, tableIDPlaceholder, endSuffix)
spanStr = fmt.Sprintf("[%s, %s)", startKeyStr, endKeyStr)
} else {
translateOutputFmt = "%-42s %s\n"
spanStr = record.GetTarget().GetSpan().String()
}
output.WriteString(fmt.Sprintf(translateOutputFmt, spanStr,
output.WriteString(fmt.Sprintf("%-42s %s\n", record.GetTarget().GetSpan(),
spanconfigtestutils.PrintSpanConfigDiffedAgainstDefaults(record.GetConfig())))
case record.GetTarget().IsSystemTarget():
output.WriteString(fmt.Sprintf("%-42s %s\n", record.GetTarget().GetSystemTarget(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ALTER INDEX db.tbl@idx2 CONFIGURE ZONE USING constraints = '[+n3]';

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/2) range default
[/Table/<table-id>/2, /Table/<table-id>/3) constraints=[+n2]
[/Table/<table-id>/3, /Table/<table-id>/4) constraints=[+n3]
[/Table/<table-id>/4, /Table/<table-id+1>) range default
/Table/106{-/2} range default
/Table/106/{2-3} constraints=[+n2]
/Table/106/{3-4} constraints=[+n3]
/Table/10{6/4-7} range default
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ALTER INDEX db.tbl@idx1 CONFIGURE ZONE USING constraints = '[+n3]';

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/2) range default
[/Table/<table-id>/2, /Table/<table-id>/3) constraints=[+n3]
[/Table/<table-id>/3, /Table/<table-id>/4) constraints=[+n2]
[/Table/<table-id>/4, /Table/<table-id+1>) range default
/Table/106{-/2} range default
/Table/106/{2-3} constraints=[+n3]
/Table/106/{3-4} constraints=[+n2]
/Table/10{6/4-7} range default
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ ALTER PARTITION pd OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints = '

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) constraints=[+n1]
[/Table/<table-id>/1, /Table/<table-id>/1/3) constraints=[+n1]
[/Table/<table-id>/1/3, /Table/<table-id>/1/3/4) constraints=[+n2]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/3/5) constraints=[+n3]
[/Table/<table-id>/1/3/5, /Table/<table-id>/1/4) constraints=[+n2]
[/Table/<table-id>/1/4, /Table/<table-id>/1/5) constraints=[+n1]
[/Table/<table-id>/1/5, /Table/<table-id>/1/5/6) constraints=[+n3]
[/Table/<table-id>/1/5/6, /Table/<table-id>/1/5/7) constraints=[+n2]
[/Table/<table-id>/1/5/7, /Table/<table-id>/1/6) constraints=[+n3]
[/Table/<table-id>/1/6, /Table/<table-id>/2) constraints=[+n1]
[/Table/<table-id>/2, /Table/<table-id+1>) constraints=[+n1]
/Table/106{-/1} constraints=[+n1]
/Table/106/1{-/3} constraints=[+n1]
/Table/106/1/3{-/4} constraints=[+n2]
/Table/106/1/3/{4-5} constraints=[+n3]
/Table/106/1/{3/5-4} constraints=[+n2]
/Table/106/1/{4-5} constraints=[+n1]
/Table/106/1/5{-/6} constraints=[+n3]
/Table/106/1/5/{6-7} constraints=[+n2]
/Table/106/1/{5/7-6} constraints=[+n3]
/Table/106/{1/6-2} constraints=[+n1]
/Table/10{6/2-7} constraints=[+n1]
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ ALTER PARTITION pd OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints = '

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) constraints=[+n1]
[/Table/<table-id>/1, /Table/<table-id>/1/3) constraints=[+n1]
[/Table/<table-id>/1/3, /Table/<table-id>/1/3/4) constraints=[+n3]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/4) constraints=[+n2]
[/Table/<table-id>/1/4, /Table/<table-id>/1/5) constraints=[+n1]
[/Table/<table-id>/1/5, /Table/<table-id>/1/5/6) constraints=[+n2]
[/Table/<table-id>/1/5/6, /Table/<table-id>/1/6) constraints=[+n3]
[/Table/<table-id>/1/6, /Table/<table-id>/2) constraints=[+n1]
[/Table/<table-id>/2, /Table/<table-id+1>) constraints=[+n1]
/Table/106{-/1} constraints=[+n1]
/Table/106/1{-/3} constraints=[+n1]
/Table/106/1/3{-/4} constraints=[+n3]
/Table/106/1/{3/4-4} constraints=[+n2]
/Table/106/1/{4-5} constraints=[+n1]
/Table/106/1/5{-/6} constraints=[+n2]
/Table/106/1/{5/6-6} constraints=[+n3]
/Table/106/{1/6-2} constraints=[+n1]
/Table/10{6/2-7} constraints=[+n1]
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ ALTER PARTITION p57 OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints =

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1/3/4) constraints=[+n1]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/3/5) constraints=[+n2]
[/Table/<table-id>/1/3/5, /Table/<table-id>/1/5/6) constraints=[+n1]
[/Table/<table-id>/1/5/6, /Table/<table-id>/1/5/7) constraints=[+n3]
[/Table/<table-id>/1/5/7, /Table/<table-id>/1/5/8) constraints=[+n1]
[/Table/<table-id>/1/5/8, /Table/<table-id+1>) constraints=[+n1]
/Table/106{-/1/3/4} constraints=[+n1]
/Table/106/1/3/{4-5} constraints=[+n2]
/Table/106/1/{3/5-5/6} constraints=[+n1]
/Table/106/1/5/{6-7} constraints=[+n3]
/Table/106/1/5/{7-8} constraints=[+n1]
/Table/10{6/1/5/8-7} constraints=[+n1]
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ ALTER PARTITION p5d OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints =

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1/3/4) constraints=[+n1]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/3/5) constraints=[+n2]
[/Table/<table-id>/1/3/5, /Table/<table-id>/1/5) constraints=[+n1]
[/Table/<table-id>/1/5, /Table/<table-id>/1/5/7) constraints=[+n2]
[/Table/<table-id>/1/5/7, /Table/<table-id>/1/5/8) constraints=[+n3]
[/Table/<table-id>/1/5/8, /Table/<table-id>/1/5/9) constraints=[+n1]
[/Table/<table-id>/1/5/9, /Table/<table-id>/1/6) constraints=[+n2]
[/Table/<table-id>/1/6, /Table/<table-id+1>) constraints=[+n1]
/Table/106{-/1/3/4} constraints=[+n1]
/Table/106/1/3/{4-5} constraints=[+n2]
/Table/106/1/{3/5-5} constraints=[+n1]
/Table/106/1/5{-/7} constraints=[+n2]
/Table/106/1/5/{7-8} constraints=[+n3]
/Table/106/1/5/{8-9} constraints=[+n1]
/Table/106/1/{5/9-6} constraints=[+n2]
/Table/10{6/1/6-7} constraints=[+n1]
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ ALTER PARTITION pd OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints = '

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) range default
[/Table/<table-id>/1, /Table/<table-id>/1/3/4) constraints=[+n2]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/3/5) constraints=[+n1]
[/Table/<table-id>/1/3/5, /Table/<table-id>/1/5) constraints=[+n2]
[/Table/<table-id>/1/5, /Table/<table-id>/1/5/7) constraints=[+n1]
[/Table/<table-id>/1/5/7, /Table/<table-id>/1/5/8) constraints=[+n2]
[/Table/<table-id>/1/5/8, /Table/<table-id>/1/5/9) constraints=[+n3]
[/Table/<table-id>/1/5/9, /Table/<table-id>/1/6) constraints=[+n1]
[/Table/<table-id>/1/6, /Table/<table-id>/2) constraints=[+n2]
[/Table/<table-id>/2, /Table/<table-id+1>) range default
/Table/106{-/1} range default
/Table/106/1{-/3/4} constraints=[+n2]
/Table/106/1/3/{4-5} constraints=[+n1]
/Table/106/1/{3/5-5} constraints=[+n2]
/Table/106/1/5{-/7} constraints=[+n1]
/Table/106/1/5/{7-8} constraints=[+n2]
/Table/106/1/5/{8-9} constraints=[+n3]
/Table/106/1/{5/9-6} constraints=[+n1]
/Table/106/{1/6-2} constraints=[+n2]
/Table/10{6/2-7} range default
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ ALTER PARTITION pd OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints = '

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) range default
[/Table/<table-id>/1, /Table/<table-id>/1/3/4) constraints=[+n2]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/3/5) constraints=[+n1]
[/Table/<table-id>/1/3/5, /Table/<table-id>/1/5) constraints=[+n2]
[/Table/<table-id>/1/5, /Table/<table-id>/1/5/7) constraints=[+n1]
[/Table/<table-id>/1/5/7, /Table/<table-id>/1/5/8) constraints=[+n2]
[/Table/<table-id>/1/5/8, /Table/<table-id>/1/5/9) constraints=[+n3]
[/Table/<table-id>/1/5/9, /Table/<table-id>/1/6) constraints=[+n1]
[/Table/<table-id>/1/6, /Table/<table-id>/2) constraints=[+n2]
[/Table/<table-id>/2, /Table/<table-id+1>) range default
/Table/106{-/1} range default
/Table/106/1{-/3/4} constraints=[+n2]
/Table/106/1/3/{4-5} constraints=[+n1]
/Table/106/1/{3/5-5} constraints=[+n2]
/Table/106/1/5{-/7} constraints=[+n1]
/Table/106/1/5/{7-8} constraints=[+n2]
/Table/106/1/5/{8-9} constraints=[+n3]
/Table/106/1/{5/9-6} constraints=[+n1]
/Table/106/{1/6-2} constraints=[+n2]
/Table/10{6/2-7} range default
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ ALTER PARTITION p57 OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints =

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) constraints=[+n1]
[/Table/<table-id>/1, /Table/<table-id>/1/3/4) constraints=[+n2]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/5/6) constraints=[+n3]
[/Table/<table-id>/1/5/6, /Table/<table-id>/1/5/7) constraints=[+n1]
[/Table/<table-id>/1/5/7, /Table/<table-id+1>) constraints=[+n1]
/Table/106{-/1} constraints=[+n1]
/Table/106/1{-/3/4} constraints=[+n2]
/Table/106/1/{3/4-5/6} constraints=[+n3]
/Table/106/1/5/{6-7} constraints=[+n1]
/Table/10{6/1/5/7-7} constraints=[+n1]
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ ALTER PARTITION pxxx OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints =

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) range default
[/Table/<table-id>/1, /Table/<table-id>/1/7) constraints=[+n1]
[/Table/<table-id>/1/7, /Table/<table-id>/1/7/-6) constraints=[+n2]
[/Table/<table-id>/1/7/-6, /Table/<table-id>/2) constraints=[+n3]
[/Table/<table-id>/2, /Table/<table-id+1>) range default
/Table/106{-/1} range default
/Table/106/1{-/7} constraints=[+n1]
/Table/106/1/7{-/-6} constraints=[+n2]
/Table/106/{1/7/-6-2} constraints=[+n3]
/Table/10{6/2-7} range default
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ ALTER PARTITION p57 OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints =

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) constraints=[+n1]
[/Table/<table-id>/1, /Table/<table-id>/1/3) constraints=[+n2]
[/Table/<table-id>/1/3, /Table/<table-id>/1/4) constraints=[+n3]
[/Table/<table-id>/1/4, /Table/<table-id>/1/5/6) constraints=[+n1]
[/Table/<table-id>/1/5/6, /Table/<table-id>/1/5/7) constraints=[+n2]
[/Table/<table-id>/1/5/7, /Table/<table-id+1>) constraints=[+n1]
/Table/106{-/1} constraints=[+n1]
/Table/106/1{-/3} constraints=[+n2]
/Table/106/1/{3-4} constraints=[+n3]
/Table/106/1/{4-5/6} constraints=[+n1]
/Table/106/1/5/{6-7} constraints=[+n2]
/Table/10{6/1/5/7-7} constraints=[+n1]
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ ALTER PARTITION pxx OF INDEX db.tbl@tbl_pkey CONFIGURE ZONE USING constraints =

translate database=db table=tbl
----
[/Table/<table-id>, /Table/<table-id>/1) range default
[/Table/<table-id>/1, /Table/<table-id>/1/3/4) constraints=[+n1]
[/Table/<table-id>/1/3/4, /Table/<table-id>/1/4) constraints=[+n2]
[/Table/<table-id>/1/4, /Table/<table-id>/1/5/6) constraints=[+n3]
[/Table/<table-id>/1/5/6, /Table/<table-id>/1/5/7) constraints=[+n1]
[/Table/<table-id>/1/5/7, /Table/<table-id>/2) constraints=[+n2]
[/Table/<table-id>/2, /Table/<table-id+1>) range default
/Table/106{-/1} range default
/Table/106/1{-/3/4} constraints=[+n1]
/Table/106/1/{3/4-4} constraints=[+n2]
/Table/106/1/{4-5/6} constraints=[+n3]
/Table/106/1/5/{6-7} constraints=[+n1]
/Table/106/{1/5/7-2} constraints=[+n2]
/Table/10{6/2-7} range default
Loading

0 comments on commit 0b2ced7

Please sign in to comment.