當前位置: 首頁>>代碼示例>>Golang>>正文


Golang sqlbase.MakeIndexKeyPrefix函數代碼示例

本文整理匯總了Golang中github.com/cockroachdb/cockroach/sql/sqlbase.MakeIndexKeyPrefix函數的典型用法代碼示例。如果您正苦於以下問題:Golang MakeIndexKeyPrefix函數的具體用法?Golang MakeIndexKeyPrefix怎麽用?Golang MakeIndexKeyPrefix使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。


在下文中一共展示了MakeIndexKeyPrefix函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。

示例1: initScan

// initScan sets up the rowFetcher and starts a scan. On error, sets n.err and
// returns false.
func (n *scanNode) initScan() (success bool) {
	// TODO(radu): we could call init() just once, after the index and
	// valNeededForCol are set.
	err := n.fetcher.Init(&n.desc, n.colIdxMap, n.index, n.reverse, n.isSecondaryIndex,
		n.valNeededForCol)
	if err != nil {
		n.err = err
		return false
	}

	if len(n.spans) == 0 {
		// If no spans were specified retrieve all of the keys that start with our
		// index key prefix. This isn't needed for the fetcher, but it is for
		// other external users of n.spans.
		start := roachpb.Key(sqlbase.MakeIndexKeyPrefix(n.desc.ID, n.index.ID))
		n.spans = append(n.spans, sqlbase.Span{Start: start, End: start.PrefixEnd()})
	}

	n.err = n.fetcher.StartScan(n.txn, n.spans, n.limitHint)
	if n.err != nil {
		return false
	}
	n.scanInitialized = true
	return true
}
開發者ID:GitGoldie,項目名稱:cockroach,代碼行數:27,代碼來源:scan.go

示例2: deleteIndexFast

func (td *tableDeleter) deleteIndexFast(ctx context.Context, idx *sqlbase.IndexDescriptor) error {
	indexPrefix := sqlbase.MakeIndexKeyPrefix(td.rd.helper.tableDesc, idx.ID)
	indexStartKey := roachpb.Key(indexPrefix)
	indexEndKey := indexStartKey.PrefixEnd()

	if log.V(2) {
		log.Infof(ctx, "DelRange %s - %s", indexStartKey, indexEndKey)
	}
	td.b.DelRange(indexStartKey, indexEndKey, false)
	return td.finalize(ctx)
}
開發者ID:yangxuanjia,項目名稱:cockroach,代碼行數:11,代碼來源:tablewriter.go

示例3: TestDropIndex

func TestDropIndex(t *testing.T) {
	defer leaktest.AfterTest(t)()
	params, _ := createTestServerParams()
	s, sqlDB, kvDB := serverutils.StartServer(t, params)
	defer s.Stopper().Stop()

	if _, err := sqlDB.Exec(`
CREATE DATABASE t;
CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR);
CREATE INDEX foo on t.kv (v);
INSERT INTO t.kv VALUES ('c', 'e'), ('a', 'c'), ('b', 'd');
`); err != nil {
		t.Fatal(err)
	}

	tableDesc := sqlbase.GetTableDescriptor(kvDB, "t", "kv")

	status, i, err := tableDesc.FindIndexByName("foo")
	if err != nil {
		t.Fatal(err)
	}
	if status != sqlbase.DescriptorActive {
		t.Fatal("Index 'foo' is not active.")
	}
	indexPrefix := sqlbase.MakeIndexKeyPrefix(tableDesc.ID, tableDesc.Indexes[i].ID)

	indexStartKey := roachpb.Key(indexPrefix)
	indexEndKey := indexStartKey.PrefixEnd()
	if kvs, err := kvDB.Scan(indexStartKey, indexEndKey, 0); err != nil {
		t.Fatal(err)
	} else if l := 3; len(kvs) != l {
		t.Fatalf("expected %d key value pairs, but got %d", l, len(kvs))
	}

	if _, err := sqlDB.Exec(`DROP INDEX [email protected]`); err != nil {
		t.Fatal(err)
	}

	if kvs, err := kvDB.Scan(indexStartKey, indexEndKey, 0); err != nil {
		t.Fatal(err)
	} else if l := 0; len(kvs) != l {
		t.Fatalf("expected %d key value pairs, but got %d", l, len(kvs))
	}

	tableDesc = sqlbase.GetTableDescriptor(kvDB, "t", "kv")

	if _, _, err := tableDesc.FindIndexByName("foo"); err == nil {
		t.Fatalf("table descriptor still contains index after index is dropped")
	}
	if err != nil {
		t.Fatal(err)
	}
}
開發者ID:CubeLite,項目名稱:cockroach,代碼行數:53,代碼來源:drop_test.go

示例4: init

func (tu *tableUpserter) init(txn *client.Txn) error {
	tu.txn = txn
	tu.tableDesc = tu.ri.helper.tableDesc
	tu.indexKeyPrefix = sqlbase.MakeIndexKeyPrefix(tu.tableDesc, tu.tableDesc.PrimaryIndex.ID)

	allColsIdentityExpr := len(tu.ri.insertCols) == len(tu.tableDesc.Columns) &&
		tu.evaler != nil && tu.evaler.isIdentityEvaler()
	if len(tu.tableDesc.Indexes) == 0 && allColsIdentityExpr {
		tu.fastPathBatch = tu.txn.NewBatch()
		tu.fastPathKeys = make(map[string]struct{})
		return nil
	}

	// TODO(dan): This could be made tighter, just the rows needed for the ON
	// CONFLICT exprs.
	requestedCols := tu.tableDesc.Columns

	var err error
	if len(tu.updateCols) == 0 {
		tu.fetchColIDtoRowIndex = colIDtoRowIndexFromCols(requestedCols)
	} else {
		tu.ru, err = makeRowUpdater(
			txn, tu.tableDesc, tu.fkTables, tu.updateCols, requestedCols, rowUpdaterDefault,
		)
		if err != nil {
			return err
		}
		tu.fetchColIDtoRowIndex = tu.ru.fetchColIDtoRowIndex

		tu.updateColIDtoRowIndex = make(map[sqlbase.ColumnID]int)
		for i, updateCol := range tu.ru.updateCols {
			tu.updateColIDtoRowIndex[updateCol.ID] = i
		}
	}

	valNeededForCol := make([]bool, len(tu.tableDesc.Columns))
	for i := range valNeededForCol {
		if _, ok := tu.fetchColIDtoRowIndex[tu.tableDesc.Columns[i].ID]; ok {
			valNeededForCol[i] = true
		}
	}
	err = tu.fetcher.Init(
		tu.tableDesc, tu.fetchColIDtoRowIndex, &tu.tableDesc.PrimaryIndex, false, false,
		tu.tableDesc.Columns, valNeededForCol)
	if err != nil {
		return err
	}

	return nil
}
開發者ID:YuleiXiao,項目名稱:cockroach,代碼行數:50,代碼來源:tablewriter.go

示例5: getTableSpan

// getTableSpan returns a span containing the start and end key for a table.
func (sc *SchemaChanger) getTableSpan() (sqlbase.Span, error) {
	var tableDesc *sqlbase.TableDescriptor
	if err := sc.db.Txn(func(txn *client.Txn) error {
		var err error
		tableDesc, err = getTableDescFromID(txn, sc.tableID)
		return err
	}); err != nil {
		return sqlbase.Span{}, err
	}
	prefix := roachpb.Key(sqlbase.MakeIndexKeyPrefix(tableDesc.ID, tableDesc.PrimaryIndex.ID))
	return sqlbase.Span{
		Start: prefix,
		End:   prefix.PrefixEnd(),
	}, nil
}
開發者ID:GitGoldie,項目名稱:cockroach,代碼行數:16,代碼來源:backfill.go

示例6: makeBaseFKHelper

func makeBaseFKHelper(
	txn *client.Txn,
	otherTables tableLookupsByID,
	writeIdx sqlbase.IndexDescriptor,
	ref sqlbase.ForeignKeyReference,
	colMap map[sqlbase.ColumnID]int, // col ids (for idx being written) to row offset.
) (baseFKHelper, error) {
	b := baseFKHelper{txn: txn, writeIdx: writeIdx, searchTable: otherTables[ref.Table].table}
	if b.searchTable == nil {
		return b, errors.Errorf("referenced table %d not in provided table map %+v", ref.Table, otherTables)
	}
	b.searchPrefix = sqlbase.MakeIndexKeyPrefix(b.searchTable, ref.Index)
	searchIdx, err := b.searchTable.FindIndexByID(ref.Index)
	if err != nil {
		return b, err
	}
	b.prefixLen = len(searchIdx.ColumnIDs)
	if len(writeIdx.ColumnIDs) < b.prefixLen {
		b.prefixLen = len(writeIdx.ColumnIDs)
	}
	b.searchIdx = searchIdx
	ids := colIDtoRowIndexFromCols(b.searchTable.Columns)
	needed := make([]bool, len(ids))
	for _, i := range searchIdx.ColumnIDs {
		needed[ids[i]] = true
	}
	isSecondary := b.searchTable.PrimaryIndex.ID != searchIdx.ID
	err = b.rf.Init(b.searchTable, ids, searchIdx, false, isSecondary, b.searchTable.Columns, needed)
	if err != nil {
		return b, err
	}

	b.ids = make(map[sqlbase.ColumnID]int, len(writeIdx.ColumnIDs))
	nulls := true
	for i, writeColID := range writeIdx.ColumnIDs[:b.prefixLen] {
		if found, ok := colMap[writeColID]; ok {
			b.ids[searchIdx.ColumnIDs[i]] = found
			nulls = false
		}
	}
	if nulls {
		return b, errSkipUnsedFK
	}
	return b, nil
}
開發者ID:yangxuanjia,項目名稱:cockroach,代碼行數:45,代碼來源:fk.go

示例7: truncateIndexes

func (sc *SchemaChanger) truncateIndexes(
	lease *sqlbase.TableDescriptor_SchemaChangeLease,
	dropped []sqlbase.IndexDescriptor,
) error {
	for _, desc := range dropped {
		// First extend the schema change lease.
		l, err := sc.ExtendLease(*lease)
		if err != nil {
			return err
		}
		*lease = l
		if err := sc.db.Txn(func(txn *client.Txn) error {
			tableDesc, err := getTableDescFromID(txn, sc.tableID)
			if err != nil {
				return err
			}
			// Short circuit the truncation if the table has been deleted.
			if tableDesc.Deleted {
				return nil
			}

			indexPrefix := sqlbase.MakeIndexKeyPrefix(tableDesc.ID, desc.ID)

			// Delete the index.
			indexStartKey := roachpb.Key(indexPrefix)
			indexEndKey := indexStartKey.PrefixEnd()
			if log.V(2) {
				log.Infof("DelRange %s - %s", indexStartKey, indexEndKey)
			}
			b := &client.Batch{}
			b.DelRange(indexStartKey, indexEndKey, false)

			if err := txn.Run(b); err != nil {
				return err
			}
			return nil
		}); err != nil {
			return err
		}
	}
	return nil
}
開發者ID:GitGoldie,項目名稱:cockroach,代碼行數:42,代碼來源:backfill.go

示例8: initScan

// initScan sets up the rowFetcher and starts a scan.
func (n *scanNode) initScan() (err error) {
	if len(n.spans) == 0 {
		// If no spans were specified retrieve all of the keys that start with our
		// index key prefix. This isn't needed for the fetcher, but it is for
		// other external users of n.spans.
		start := roachpb.Key(sqlbase.MakeIndexKeyPrefix(n.desc.ID, n.index.ID))
		n.spans = append(n.spans, sqlbase.Span{Start: start, End: start.PrefixEnd()})
	}

	limitHint := n.limitHint
	if limitHint != 0 && n.limitSoft {
		// Read a multiple of the limit if the limit is "soft".
		limitHint *= 2
	}

	if err := n.fetcher.StartScan(n.p.txn, n.spans, limitHint); err != nil {
		return err
	}
	n.scanInitialized = true
	return nil
}
開發者ID:JKhawaja,項目名稱:cockroach,代碼行數:22,代碼來源:scan.go

示例9: encodeIndexes

// encodeIndexes encodes the primary and secondary index keys. The
// secondaryIndexEntries are only valid until the next call to encodeIndexes or
// encodeSecondaryIndexes.
func (rh *rowHelper) encodeIndexes(
	colIDtoRowIndex map[sqlbase.ColumnID]int, values []parser.Datum,
) (
	primaryIndexKey []byte,
	secondaryIndexEntries []sqlbase.IndexEntry,
	err error,
) {
	if rh.primaryIndexKeyPrefix == nil {
		rh.primaryIndexKeyPrefix = sqlbase.MakeIndexKeyPrefix(rh.tableDesc,
			rh.tableDesc.PrimaryIndex.ID)
	}
	primaryIndexKey, _, err = sqlbase.EncodeIndexKey(
		rh.tableDesc, &rh.tableDesc.PrimaryIndex, colIDtoRowIndex, values, rh.primaryIndexKeyPrefix)
	if err != nil {
		return nil, nil, err
	}
	secondaryIndexEntries, err = rh.encodeSecondaryIndexes(colIDtoRowIndex, values)
	if err != nil {
		return nil, nil, err
	}
	return primaryIndexKey, secondaryIndexEntries, nil
}
開發者ID:YuleiXiao,項目名稱:cockroach,代碼行數:25,代碼來源:rowwriter.go

示例10: deleteAllRowsScan

func (td *tableDeleter) deleteAllRowsScan(ctx context.Context) error {
	tablePrefix := sqlbase.MakeIndexKeyPrefix(
		td.rd.helper.tableDesc, td.rd.helper.tableDesc.PrimaryIndex.ID)
	span := sqlbase.Span{Start: roachpb.Key(tablePrefix), End: roachpb.Key(tablePrefix).PrefixEnd()}

	valNeededForCol := make([]bool, len(td.rd.helper.tableDesc.Columns))
	for _, idx := range td.rd.fetchColIDtoRowIndex {
		valNeededForCol[idx] = true
	}

	var rf sqlbase.RowFetcher
	err := rf.Init(
		td.rd.helper.tableDesc, td.rd.fetchColIDtoRowIndex, &td.rd.helper.tableDesc.PrimaryIndex,
		false, false, td.rd.fetchCols, valNeededForCol)
	if err != nil {
		return err
	}
	if err := rf.StartScan(td.txn, sqlbase.Spans{span}, 0); err != nil {
		return err
	}

	for {
		row, err := rf.NextRow()
		if err != nil {
			return err
		}
		if row == nil {
			// Done deleting rows.
			break
		}
		_, err = td.row(ctx, row)
		if err != nil {
			return err
		}
	}
	return td.finalize(ctx)
}
開發者ID:yangxuanjia,項目名稱:cockroach,代碼行數:37,代碼來源:tablewriter.go

示例11: restoreTable

func restoreTable(
	ctx context.Context,
	sst engine.RocksDBSstFileReader,
	txn *client.Txn,
	table *sqlbase.TableDescriptor,
	overwrite bool,
) error {
	log.Infof(ctx, "Restoring Table %q", table.Name)

	tableStartKey := roachpb.Key(sqlbase.MakeIndexKeyPrefix(table, table.PrimaryIndex.ID))
	tableEndKey := tableStartKey.PrefixEnd()

	existingDesc, err := txn.Get(sqlbase.MakeDescMetadataKey(table.GetID()))
	if err != nil {
		return err
	}
	existingData, err := txn.Scan(tableStartKey, tableEndKey, 1)
	if err != nil {
		return err
	}
	if existingDesc.Value != nil || len(existingData) > 0 {
		if overwrite {
			// We're about to Put the descriptor, so don't bother deleting it.
			if err := txn.DelRange(tableStartKey, tableEndKey); err != nil {
				return err
			}
		} else {
			return errors.Errorf("table %q already exists", table.Name)
		}
	}
	tableDescKey := sqlbase.MakeDescMetadataKey(table.GetID())
	if err := txn.Put(tableDescKey, sqlbase.WrapDescriptor(table)); err != nil {
		return err
	}

	return Import(ctx, sst, txn, engine.MVCCKey{Key: tableStartKey}, engine.MVCCKey{Key: tableEndKey})
}
開發者ID:yaojingguo,項目名稱:cockroach,代碼行數:37,代碼來源:backup.go

示例12: init

func (tu *tableUpserter) init(txn *client.Txn) error {
	tu.txn = txn

	tu.tableDesc = tu.ri.helper.tableDesc
	tu.indexKeyPrefix = sqlbase.MakeIndexKeyPrefix(tu.tableDesc.ID, tu.tableDesc.PrimaryIndex.ID)

	tu.updateColIDtoRowIndex = make(map[sqlbase.ColumnID]int)
	for i, updateCol := range tu.ru.updateCols {
		tu.updateColIDtoRowIndex[updateCol.ID] = i
	}
	tu.updateRow = make(parser.DTuple, len(tu.updateColIDtoRowIndex))

	valNeededForCol := make([]bool, len(tu.ru.fetchCols))
	for i := range valNeededForCol {
		valNeededForCol[i] = true
	}
	err := tu.fetcher.Init(
		tu.tableDesc, tu.ru.fetchColIDtoRowIndex, &tu.tableDesc.PrimaryIndex,
		false, false, valNeededForCol)
	if err != nil {
		return err
	}
	return nil
}
開發者ID:GitGoldie,項目名稱:cockroach,代碼行數:24,代碼來源:tablewriter.go

示例13: TestTableReader

func TestTableReader(t *testing.T) {
	defer leaktest.AfterTest(t)()

	_, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t)
	defer cleanup()

	// Create a table where each row is:
	//
	//  |     a    |     b    |         sum         |         s           |
	//  |-----------------------------------------------------------------|
	//  | rowId/10 | rowId%10 | rowId/10 + rowId%10 | IntToEnglish(rowId) |

	aFn := func(row int) parser.Datum {
		return parser.NewDInt(parser.DInt(row / 10))
	}
	bFn := func(row int) parser.Datum {
		return parser.NewDInt(parser.DInt(row % 10))
	}
	sumFn := func(row int) parser.Datum {
		return parser.NewDInt(parser.DInt(row/10 + row%10))
	}

	sqlutils.CreateTable(t, sqlDB, "t",
		"a INT, b INT, sum INT, s STRING, PRIMARY KEY (a,b), INDEX bs (b,s)",
		99,
		sqlutils.ToRowFn(aFn, bFn, sumFn, sqlutils.RowEnglishFn))

	td := sqlbase.GetTableDescriptor(kvDB, "test", "t")

	makeIndexSpan := func(start, end int) TableReaderSpan {
		var span roachpb.Span
		prefix := roachpb.Key(sqlbase.MakeIndexKeyPrefix(td.ID, td.Indexes[0].ID))
		span.Key = append(prefix, encoding.EncodeVarintAscending(nil, int64(start))...)
		span.EndKey = append(span.EndKey, prefix...)
		span.EndKey = append(span.EndKey, encoding.EncodeVarintAscending(nil, int64(end))...)
		return TableReaderSpan{Span: span}
	}

	testCases := []struct {
		spec     TableReaderSpec
		expected string
	}{
		{
			spec: TableReaderSpec{
				Filter:        Expression{Expr: "$2 < 5 AND $1 != 3"}, // sum < 5 && b != 3
				OutputColumns: []uint32{0, 1},
			},
			expected: "[[0 1] [0 2] [0 4] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2] [3 0] [3 1] [4 0]]",
		},
		{
			spec: TableReaderSpec{
				Filter:        Expression{Expr: "$2 < 5 AND $1 != 3"},
				OutputColumns: []uint32{3}, // s
				HardLimit:     4,
			},
			expected: "[['one'] ['two'] ['four'] ['one-zero']]",
		},
		{
			spec: TableReaderSpec{
				IndexIdx:      1,
				Reverse:       true,
				Spans:         []TableReaderSpan{makeIndexSpan(4, 6)},
				Filter:        Expression{Expr: "$0 < 3"}, // sum < 8
				OutputColumns: []uint32{0, 1},
				SoftLimit:     1,
			},
			expected: "[[2 5] [1 5] [0 5] [2 4] [1 4] [0 4]]",
		},
	}

	for _, c := range testCases {
		ts := c.spec
		ts.Table = *td

		txn := client.NewTxn(context.Background(), *kvDB)

		out := &RowBuffer{}
		tr, err := newTableReader(&ts, txn, out, &parser.EvalContext{})
		if err != nil {
			t.Fatal(err)
		}
		tr.Run(nil)
		if out.err != nil {
			t.Fatal(out.err)
		}
		if !out.closed {
			t.Fatalf("output RowReceiver not closed")
		}
		if result := out.rows.String(); result != c.expected {
			t.Errorf("invalid results: %s, expected %s'", result, c.expected)
		}
	}
}
開發者ID:the872,項目名稱:cockroach,代碼行數:93,代碼來源:tablereader_test.go

示例14: mainLoop

// mainLoop runs the mainLoop and returns any error.
// It does not close the output.
func (jr *joinReader) mainLoop() error {
	primaryKeyPrefix := sqlbase.MakeIndexKeyPrefix(&jr.desc, jr.index.ID)

	var alloc sqlbase.DatumAlloc
	spans := make(sqlbase.Spans, 0, joinReaderBatchSize)

	for {
		// TODO(radu): figure out how to send smaller batches if the source has
		// a soft limit (perhaps send the batch out if we don't get a result
		// within a certain amount of time).
		for spans = spans[:0]; len(spans) < joinReaderBatchSize; {
			row, err := jr.input.NextRow()
			if err != nil {
				return err
			}
			if row == nil {
				if len(spans) == 0 {
					return nil
				}
				break
			}
			key, err := jr.generateKey(row, &alloc, primaryKeyPrefix)
			if err != nil {
				return err
			}

			spans = append(spans, sqlbase.Span{
				Start: key,
				End:   key.PrefixEnd(),
			})
		}

		err := jr.fetcher.StartScan(jr.txn, spans, 0)
		if err != nil {
			return err
		}

		// TODO(radu): we are consuming all results from a fetch before starting
		// the next batch. We could start the next batch early while we are
		// outputting rows.
		for {
			outRow, err := jr.nextRow()
			if err != nil {
				return err
			}
			if outRow == nil {
				// Done.
				break
			}
			// Push the row to the output RowReceiver; stop if they don't need more
			// rows.
			if !jr.output.PushRow(outRow) {
				return nil
			}
		}

		if len(spans) != joinReaderBatchSize {
			// This was the last batch.
			return nil
		}
	}
}
開發者ID:YuleiXiao,項目名稱:cockroach,代碼行數:64,代碼來源:joinreader.go

示例15: TestMakeSpans


//.........這裏部分代碼省略.........
		{`(a > 1 AND b < 5) OR (a < 3 AND b > 7)`, `a`, `/#-`, `-/#`},
		{`(a > 1 AND b < 5) OR (a < 3 AND b > 7)`, `b`, `/#-/5 /8-`, `-/7 /4-/#`},
		{`(a > 1 AND b < 5) OR (a < 3 AND b > 7)`, `a,b`, `/#-`, `-/#`},

		{`(a = 5) OR (a, b) IN ((1, 1), (3, 3))`, `a`, `/1-/2 /3-/4 /5-/6`, `/5-/4 /3-/2 /1-/0`},
		{`(a = 5) OR (a, b) IN ((1, 1), (3, 3))`, `b`, `-`, `-`},
		{`(a = 5) OR (a, b) IN ((1, 1), (3, 3))`, `a,b`,
			`/1/1-/1/2 /3/3-/3/4 /5-/6`, `/5-/4 /3/3-/3/2 /1/1-/1/0`},

		// When encoding an end constraint for a maximal datum, we use
		// bytes.PrefixEnd() to go beyond the normal encodings of that datatype.
		{fmt.Sprintf(`a = %d`, math.MaxInt64), `a`,
			`/9223372036854775807-/<varint 9223372036854775808 overflows int64>`,
			`/9223372036854775807-/9223372036854775806`},
		{fmt.Sprintf(`a = %d`, math.MinInt64), `a`,
			`/-9223372036854775808-/-9223372036854775807`,
			`/-9223372036854775808-/<varint 9223372036854775808 overflows int64>`},

		{`(a, b) >= (1, 4)`, `a,b`, `/1/4-`, `-/1/3`},
		{`(a, b) > (1, 4)`, `a,b`, `/1/5-`, `-/1/4`},
		{`(a, b) < (1, 4)`, `a,b`, `/#-/1/4`, `/1/3-/#`},
		{`(a, b) <= (1, 4)`, `a,b`, `/#-/1/5`, `/1/4-/#`},
		{`(a, b) = (1, 4)`, `a,b`, `/1/4-/1/5`, `/1/4-/1/3`},
		{`(a, b) != (1, 4)`, `a,b`, `/#-`, `-/#`},
	}
	for _, d := range testData {
		for _, dir := range []encoding.Direction{encoding.Ascending, encoding.Descending} {
			columns := strings.Split(d.columns, ",")
			dirs := make([]encoding.Direction, 0, len(columns))
			for range columns {
				dirs = append(dirs, dir)
			}
			desc, index := makeTestIndex(t, columns, dirs)
			constraints, _ := makeConstraints(t, d.expr, desc, index)
			spans := makeSpans(constraints, desc.ID, index)
			s := sqlbase.PrettySpans(spans, 2)
			var expected string
			if dir == encoding.Ascending {
				expected = d.expectedAsc
			} else {
				expected = d.expectedDesc
			}
			s = keys.MassagePrettyPrintedSpanForTest(s, indexToDirs(index))
			if expected != s {
				t.Errorf("[index direction: %d] %s: expected %s, but found %s", dir, d.expr, expected, s)
			}
		}
	}

	// Test indexes with mixed-directions (some cols Asc, some cols Desc) and other edge cases.
	testData2 := []struct {
		expr     string
		columns  string
		expected string
	}{
		{`a = 1 AND b = 5`, `a,b-,c`, `/1/5-/1/4`},
		{`a = 7 AND b IN (1,2,3) AND c = false`, `a,b-,c`,
			`/7/3/0-/7/3/1 /7/2/0-/7/2/1 /7/1/0-/7/1/1`},
		// Test different directions for te columns inside a tuple.
		{`(a,b,j) IN ((1,2,3), (4,5,6))`, `a-,b,j-`, `/4/5/6-/4/5/5 /1/2/3-/1/2/2`},
		{`i = E'\xff'`, `i`, `/"\xff"-/"\xff\x00"`},
		// Test that limits on bytes work correctly: when encoding a descending limit for bytes,
		// we need to go outside the bytes encoding.
		// "\xaa" is encoded as [bytesDescMarker, ^0xaa, <term escape sequence>]
		{`i = E'\xaa'`, `i-`,
			fmt.Sprintf("raw:%c%c\xff\xfe-%c%c\xff\xff",
				encoding.BytesDescMarker, ^byte(0xaa), encoding.BytesDescMarker, ^byte(0xaa))},

		// Ensure tuples with differing index directions aren't constrained.
		// TODO(mjibson): fix this, see #6346
		{`(a, b) >= (1, 4)`, `a-,b`, `-`},
		{`(a, b) >= (1, 4)`, `a,b-`, `-`},
	}
	for _, d := range testData2 {
		desc, index := makeTestIndexFromStr(t, d.columns)
		constraints, _ := makeConstraints(t, d.expr, desc, index)
		spans := makeSpans(constraints, desc.ID, index)
		var got string
		raw := false
		if strings.HasPrefix(d.expected, "raw:") {
			raw = true
			span := spans[0]
			d.expected = d.expected[4:]
			// Trim the index prefix from the span.
			prefix := string(sqlbase.MakeIndexKeyPrefix(desc.ID, index.ID))
			got = strings.TrimPrefix(string(span.Start), prefix) + "-" +
				strings.TrimPrefix(string(span.End), prefix)
		} else {
			got = keys.MassagePrettyPrintedSpanForTest(sqlbase.PrettySpans(spans, 2),
				indexToDirs(index))
		}
		if d.expected != got {
			if !raw {
				t.Errorf("%s: expected %s, but found %s", d.expr, d.expected, got)
			} else {
				t.Errorf("%s: expected %# x, but found %# x", d.expr, []byte(d.expected), got)
			}
		}
	}
}
開發者ID:CubeLite,項目名稱:cockroach,代碼行數:101,代碼來源:index_selection_test.go


注:本文中的github.com/cockroachdb/cockroach/sql/sqlbase.MakeIndexKeyPrefix函數示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。