Search in sources :

Example 1 with SecondaryIndexPrefixScan

use of herddb.index.SecondaryIndexPrefixScan in project herddb by diennea.

the class SecondaryIndexAccessSuite method secondaryIndexPrefixScan.

@Test
public void secondaryIndexPrefixScan() throws Exception {
    String nodeId = "localhost";
    try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
        manager.start();
        CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
        manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        manager.waitForTablespace("tblspace1", 10000);
        Table table = Table.builder().tablespace("tblspace1").name("t1").column("id", ColumnTypes.STRING).column("n1", ColumnTypes.INTEGER).column("name", ColumnTypes.STRING).primaryKey("id").build();
        CreateTableStatement st2 = new CreateTableStatement(table);
        manager.executeStatement(st2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        Index index = Index.builder().onTable(table).type(Index.TYPE_BRIN).column("n1", ColumnTypes.INTEGER).column("name", ColumnTypes.STRING).build();
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,name) values('a',1,'n1')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,name) values('b',1,'n1')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,name) values('c',1,'n2')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,name) values('d',2,'n2')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,name) values('e',3,'n2')", Collections.emptyList());
        // create index, it will be built using existing data
        CreateIndexStatement st3 = new CreateIndexStatement(index);
        manager.executeStatement(st3, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT * FROM tblspace1.t1 WHERE n1=1", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            assertTrue(scan.getPredicate().getIndexOperation() instanceof SecondaryIndexPrefixScan);
            try (DataScanner scan1 = manager.scan(scan, translated.context, TransactionContext.NO_TRANSACTION)) {
                assertEquals(3, scan1.consume().size());
            }
        }
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT * FROM tblspace1.t1 WHERE n1=1 and name='n2'", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            assertTrue(scan.getPredicate().getIndexOperation() instanceof SecondaryIndexSeek);
            try (DataScanner scan1 = manager.scan(scan, translated.context, TransactionContext.NO_TRANSACTION)) {
                assertEquals(1, scan1.consume().size());
            }
        }
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT * FROM tblspace1.t1 WHERE n1>=1", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            assertNull(scan.getPredicate().getIndexOperation());
            try (DataScanner scan1 = manager.scan(scan, translated.context, TransactionContext.NO_TRANSACTION)) {
                assertEquals(5, scan1.consume().size());
            }
        }
    }
}
Also used : Table(herddb.model.Table) TranslatedQuery(herddb.sql.TranslatedQuery) MemoryDataStorageManager(herddb.mem.MemoryDataStorageManager) CreateTableStatement(herddb.model.commands.CreateTableStatement) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) Index(herddb.model.Index) CreateTableSpaceStatement(herddb.model.commands.CreateTableSpaceStatement) DataScanner(herddb.model.DataScanner) SecondaryIndexSeek(herddb.index.SecondaryIndexSeek) MemoryCommitLogManager(herddb.mem.MemoryCommitLogManager) SecondaryIndexPrefixScan(herddb.index.SecondaryIndexPrefixScan) MemoryMetadataStorageManager(herddb.mem.MemoryMetadataStorageManager) ScanStatement(herddb.model.commands.ScanStatement) Test(org.junit.Test)

Example 2 with SecondaryIndexPrefixScan

use of herddb.index.SecondaryIndexPrefixScan in project herddb by diennea.

the class SecondaryIndexAccessSuite method secondaryIndexPrefixScanInSubquery.

@Test
public void secondaryIndexPrefixScanInSubquery() throws Exception {
    String nodeId = "localhost";
    try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
        manager.start();
        CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("q1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
        manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        manager.waitForTablespace("q1", 10000);
        Table q1_message = Table.builder().tablespace("q1").name("q1_message").column("id", ColumnTypes.INTEGER).column("subject", ColumnTypes.STRING).primaryKey("id").build();
        Table q1_headers = Table.builder().tablespace("q1").name("q1_headers").column("id", ColumnTypes.INTEGER).column("msgid", ColumnTypes.INTEGER).column("name", ColumnTypes.STRING).column("value", ColumnTypes.STRING).primaryKey("id", true).build();
        CreateTableStatement stc1 = new CreateTableStatement(q1_message);
        manager.executeStatement(stc1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        CreateTableStatement st2 = new CreateTableStatement(q1_headers);
        manager.executeStatement(st2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        Index index = Index.builder().onTable(q1_headers).type(Index.TYPE_BRIN).column("name", ColumnTypes.STRING).column("value", ColumnTypes.STRING).build();
        TestUtils.executeUpdate(manager, "INSERT INTO q1.q1_message(id,subject) values(1,'test1')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO q1.q1_message(id,subject) values(2,'test2')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO q1.q1_headers(msgid,name,`value`) values(1,'from','test@localhost')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO q1.q1_headers(msgid,name,`value`) values(1,'to','test@localhost')", Collections.emptyList());
        // create index, it will be built using existing data
        CreateIndexStatement st3 = new CreateIndexStatement(index);
        manager.executeStatement(st3, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT msgid " + "from q1.q1_headers " + "where name='from' " + "and `value`='test@localhost'", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            assertTrue(scan.getPredicate().getIndexOperation() instanceof SecondaryIndexSeek);
            try (DataScanner scan1 = manager.scan(scan, translated.context, TransactionContext.NO_TRANSACTION)) {
                List<DataAccessor> consume = scan1.consume();
                System.out.println("consume:" + consume);
                assertEquals(1, consume.size());
            }
        }
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT msgid " + "from q1.q1_headers " + "where name='from' " + "and `value` like '%test@localhost%'", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            assertTrue(scan.getPredicate().getIndexOperation() instanceof SecondaryIndexPrefixScan);
            try (DataScanner scan1 = manager.scan(scan, translated.context, TransactionContext.NO_TRANSACTION)) {
                assertEquals(1, scan1.consume().size());
            }
        }
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT * " + "FROM q1.q1_message " + "WHERE id in " + "(SELECT msgid from q1.q1_headers " + "where name='from' " + "and `value`='test@localhost')", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            try (DataScanner scan1 = ((ScanResult) manager.executePlan(translated.plan, translated.context, TransactionContext.NO_TRANSACTION)).dataScanner) {
                assertEquals(1, scan1.consume().size());
            }
        }
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT * " + "FROM q1.q1_message " + "WHERE id in " + "(SELECT msgid from q1.q1_headers " + "where name='from' " + "and `value` like '%test@%')", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            try (DataScanner scan1 = ((ScanResult) manager.executePlan(translated.plan, translated.context, TransactionContext.NO_TRANSACTION)).dataScanner) {
                assertEquals(1, scan1.consume().size());
            }
        }
    }
}
Also used : Table(herddb.model.Table) TranslatedQuery(herddb.sql.TranslatedQuery) MemoryDataStorageManager(herddb.mem.MemoryDataStorageManager) CreateTableStatement(herddb.model.commands.CreateTableStatement) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) Index(herddb.model.Index) CreateTableSpaceStatement(herddb.model.commands.CreateTableSpaceStatement) SecondaryIndexSeek(herddb.index.SecondaryIndexSeek) DataScanner(herddb.model.DataScanner) MemoryCommitLogManager(herddb.mem.MemoryCommitLogManager) List(java.util.List) SecondaryIndexPrefixScan(herddb.index.SecondaryIndexPrefixScan) MemoryMetadataStorageManager(herddb.mem.MemoryMetadataStorageManager) ScanStatement(herddb.model.commands.ScanStatement) Test(org.junit.Test)

Example 3 with SecondaryIndexPrefixScan

use of herddb.index.SecondaryIndexPrefixScan in project herddb by diennea.

the class IndexScanRangeTest method secondaryIndexPrefixScan.

private void secondaryIndexPrefixScan(String indexType) throws Exception {
    String nodeId = "localhost";
    try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
        manager.start();
        CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
        manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        manager.waitForTablespace("tblspace1", 10000);
        Table table = Table.builder().tablespace("tblspace1").name("t1").column("id", ColumnTypes.STRING).column("n1", ColumnTypes.INTEGER).column("n2", ColumnTypes.INTEGER).column("name", ColumnTypes.STRING).primaryKey("id").build();
        CreateTableStatement st2 = new CreateTableStatement(table);
        manager.executeStatement(st2, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        Index index = Index.builder().onTable(table).type(indexType).column("n1", ColumnTypes.INTEGER).column("n2", ColumnTypes.INTEGER).build();
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,n2,name) values('a',1,5,'n1')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,n2,name) values('b',2,5,'n1')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,n2,name) values('c',2,5,'n2')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,n2,name) values('d',2,5,'n2')", Collections.emptyList());
        TestUtils.executeUpdate(manager, "INSERT INTO tblspace1.t1(id,n1,n2,name) values('e',3,5,'n2')", Collections.emptyList());
        // create index, it will be built using existing data
        CreateIndexStatement st3 = new CreateIndexStatement(index);
        manager.executeStatement(st3, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
        {
            TranslatedQuery translated = manager.getPlanner().translate(TableSpace.DEFAULT, "SELECT * FROM tblspace1.t1 WHERE n1=2", Collections.emptyList(), true, true, false, -1);
            ScanStatement scan = translated.plan.mainStatement.unwrap(ScanStatement.class);
            assertTrue(scan.getPredicate().getIndexOperation() instanceof SecondaryIndexPrefixScan);
            try (DataScanner scan1 = manager.scan(scan, translated.context, TransactionContext.NO_TRANSACTION)) {
                assertEquals(3, scan1.consume().size());
            }
        }
    }
}
Also used : Table(herddb.model.Table) TranslatedQuery(herddb.sql.TranslatedQuery) MemoryDataStorageManager(herddb.mem.MemoryDataStorageManager) CreateTableStatement(herddb.model.commands.CreateTableStatement) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) Index(herddb.model.Index) CreateTableSpaceStatement(herddb.model.commands.CreateTableSpaceStatement) DataScanner(herddb.model.DataScanner) MemoryCommitLogManager(herddb.mem.MemoryCommitLogManager) SecondaryIndexPrefixScan(herddb.index.SecondaryIndexPrefixScan) MemoryMetadataStorageManager(herddb.mem.MemoryMetadataStorageManager) ScanStatement(herddb.model.commands.ScanStatement)

Example 4 with SecondaryIndexPrefixScan

use of herddb.index.SecondaryIndexPrefixScan in project herddb by diennea.

the class BRINIndexManager method scanner.

@Override
protected Stream<Bytes> scanner(IndexOperation operation, StatementEvaluationContext context, TableContext tableContext) throws StatementExecutionException {
    if (operation instanceof SecondaryIndexSeek) {
        SecondaryIndexSeek sis = (SecondaryIndexSeek) operation;
        SQLRecordKeyFunction value = sis.value;
        byte[] refvalue = value.computeNewValue(null, context, tableContext);
        List<Bytes> result = data.search(Bytes.from_array(refvalue));
        if (result != null) {
            return result.stream();
        } else {
            return Stream.empty();
        }
    } else if (operation instanceof SecondaryIndexPrefixScan) {
        SecondaryIndexPrefixScan sis = (SecondaryIndexPrefixScan) operation;
        SQLRecordKeyFunction value = sis.value;
        byte[] refvalue = value.computeNewValue(null, context, tableContext);
        Bytes firstKey = Bytes.from_array(refvalue);
        Bytes lastKey = firstKey.next();
        return data.query(firstKey, lastKey);
    } else if (operation instanceof SecondaryIndexRangeScan) {
        Bytes firstKey = null;
        Bytes lastKey = null;
        SecondaryIndexRangeScan sis = (SecondaryIndexRangeScan) operation;
        SQLRecordKeyFunction minKey = sis.minValue;
        if (minKey != null) {
            byte[] refminvalue = minKey.computeNewValue(null, context, tableContext);
            firstKey = Bytes.from_array(refminvalue);
        }
        SQLRecordKeyFunction maxKey = sis.maxValue;
        if (maxKey != null) {
            byte[] refmaxvalue = maxKey.computeNewValue(null, context, tableContext);
            lastKey = Bytes.from_array(refmaxvalue);
        }
        LOGGER.log(Level.FINE, "range scan on {0}.{1}, from {2} to {1}", new Object[] { index.table, index.name, firstKey, lastKey });
        return data.query(firstKey, lastKey);
    } else {
        throw new UnsupportedOperationException("unsuppported index access type " + operation);
    }
}
Also used : Bytes(herddb.utils.Bytes) SecondaryIndexSeek(herddb.index.SecondaryIndexSeek) SecondaryIndexRangeScan(herddb.index.SecondaryIndexRangeScan) SecondaryIndexPrefixScan(herddb.index.SecondaryIndexPrefixScan) SQLRecordKeyFunction(herddb.sql.SQLRecordKeyFunction)

Example 5 with SecondaryIndexPrefixScan

use of herddb.index.SecondaryIndexPrefixScan in project herddb by diennea.

the class CalcitePlanner method findSecondaryIndexOperation.

private static IndexOperation findSecondaryIndexOperation(AbstractIndexManager index, CompiledSQLExpression where, Table table) throws StatementExecutionException {
    IndexOperation secondaryIndexOperation = null;
    String[] columnsToMatch = index.getColumnNames();
    SQLRecordKeyFunction indexSeekFunction = findIndexAccess(where, columnsToMatch, index.getIndex(), "=", table);
    if (indexSeekFunction != null) {
        if (indexSeekFunction.isFullPrimaryKey()) {
            secondaryIndexOperation = new SecondaryIndexSeek(index.getIndexName(), columnsToMatch, indexSeekFunction);
        } else {
            secondaryIndexOperation = new SecondaryIndexPrefixScan(index.getIndexName(), columnsToMatch, indexSeekFunction);
        }
    } else {
        SQLRecordKeyFunction rangeMin = findIndexAccess(where, columnsToMatch, index.getIndex(), ">=", table);
        if (rangeMin != null && !rangeMin.isFullPrimaryKey()) {
            rangeMin = null;
        }
        if (rangeMin == null) {
            rangeMin = findIndexAccess(where, columnsToMatch, index.getIndex(), ">", table);
            if (rangeMin != null && !rangeMin.isFullPrimaryKey()) {
                rangeMin = null;
            }
        }
        SQLRecordKeyFunction rangeMax = findIndexAccess(where, columnsToMatch, index.getIndex(), "<=", table);
        if (rangeMax != null && !rangeMax.isFullPrimaryKey()) {
            rangeMax = null;
        }
        if (rangeMax == null) {
            rangeMax = findIndexAccess(where, columnsToMatch, index.getIndex(), "<", table);
            if (rangeMax != null && !rangeMax.isFullPrimaryKey()) {
                rangeMax = null;
            }
        }
        if (rangeMin != null || rangeMax != null) {
            secondaryIndexOperation = new SecondaryIndexRangeScan(index.getIndexName(), columnsToMatch, rangeMin, rangeMax);
        }
    }
    return secondaryIndexOperation;
}
Also used : IndexOperation(herddb.index.IndexOperation) SecondaryIndexSeek(herddb.index.SecondaryIndexSeek) SecondaryIndexRangeScan(herddb.index.SecondaryIndexRangeScan) SecondaryIndexPrefixScan(herddb.index.SecondaryIndexPrefixScan)

Aggregations

SecondaryIndexPrefixScan (herddb.index.SecondaryIndexPrefixScan)6 SecondaryIndexSeek (herddb.index.SecondaryIndexSeek)5 SecondaryIndexRangeScan (herddb.index.SecondaryIndexRangeScan)3 MemoryCommitLogManager (herddb.mem.MemoryCommitLogManager)3 MemoryDataStorageManager (herddb.mem.MemoryDataStorageManager)3 MemoryMetadataStorageManager (herddb.mem.MemoryMetadataStorageManager)3 DataScanner (herddb.model.DataScanner)3 Index (herddb.model.Index)3 Table (herddb.model.Table)3 CreateIndexStatement (herddb.model.commands.CreateIndexStatement)3 CreateTableSpaceStatement (herddb.model.commands.CreateTableSpaceStatement)3 CreateTableStatement (herddb.model.commands.CreateTableStatement)3 ScanStatement (herddb.model.commands.ScanStatement)3 TranslatedQuery (herddb.sql.TranslatedQuery)3 IndexOperation (herddb.index.IndexOperation)2 Test (org.junit.Test)2 SQLRecordKeyFunction (herddb.sql.SQLRecordKeyFunction)1 Bytes (herddb.utils.Bytes)1 List (java.util.List)1 GreaterThan (net.sf.jsqlparser.expression.operators.relational.GreaterThan)1