Java Code Examples for org.apache.phoenix.schema.PTable#isTransactional()

The following examples show how to use org.apache.phoenix.schema.PTable#isTransactional() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: IndexToolIT.java    From phoenix with Apache License 2.0 6 votes vote down vote up
private static void verifyMapper(Job job, boolean directApi, boolean useSnapshot, String schemaName,
                              String dataTableName, String indexTableName, String tenantId) throws Exception {
    Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
    if (tenantId != null) {
        props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
    }
    try (Connection conn =
                 DriverManager.getConnection(getUrl(), props)) {
        PTable dataTable = PhoenixRuntime.getTable(conn, SchemaUtil.getTableName(schemaName, dataTableName));
        PTable indexTable = PhoenixRuntime.getTable(conn, SchemaUtil.getTableName(schemaName, indexTableName));
        boolean transactional = dataTable.isTransactional();
        boolean localIndex = PTable.IndexType.LOCAL.equals(indexTable.getIndexType());

        if ((localIndex || !transactional) && !useSnapshot) {
            assertEquals(job.getMapperClass(), PhoenixServerBuildIndexMapper.class);
        } else {
            assertEquals(job.getMapperClass(), PhoenixIndexImportDirectMapper.class);
        }
    }
}
 
Example 2
Source File: BaseQueryPlan.java    From phoenix with Apache License 2.0 6 votes vote down vote up
private void serializeIndexMaintainerIntoScan(Scan scan, PTable dataTable) throws SQLException {
    PName name = context.getCurrentTable().getTable().getName();
    List<PTable> indexes = Lists.newArrayListWithExpectedSize(1);
    for (PTable index : dataTable.getIndexes()) {
        if (index.getName().equals(name) && index.getIndexType() == IndexType.LOCAL) {
            indexes.add(index);
            break;
        }
    }
    ImmutableBytesWritable ptr = new ImmutableBytesWritable();
    IndexMaintainer.serialize(dataTable, ptr, indexes, context.getConnection());
    scan.setAttribute(BaseScannerRegionObserver.LOCAL_INDEX_BUILD_PROTO, ByteUtil.copyKeyBytesIfNecessary(ptr));
    if (dataTable.isTransactional()) {
        scan.setAttribute(BaseScannerRegionObserver.TX_STATE, context.getConnection().getMutationState().encodeTransaction());
    }
}
 
Example 3
Source File: DeleteCompiler.java    From phoenix with Apache License 2.0 5 votes vote down vote up
private static boolean isMaintainedOnClient(PTable table) {
    // Test for not being local (rather than being GLOBAL) so that this doesn't fail
    // when tested with our projected table.
    return (table.getIndexType() != IndexType.LOCAL && (table.isTransactional() || table.isImmutableRows())) ||
           (table.getIndexType() == IndexType.LOCAL && (table.isTransactional() &&
            table.getTransactionProvider().getTransactionProvider().isUnsupported(Feature.MAINTAIN_LOCAL_INDEX_ON_SERVER) ) );
}
 
Example 4
Source File: UpsertCompiler.java    From phoenix with Apache License 2.0 5 votes vote down vote up
@Override
public MutationState execute() throws SQLException {
    ImmutableBytesWritable ptr = context.getTempPtr();
    PTable table = tableRef.getTable();
    table.getIndexMaintainers(ptr, context.getConnection());
    byte[] txState = table.isTransactional() ?
            connection.getMutationState().encodeTransaction() : ByteUtil.EMPTY_BYTE_ARRAY;

    ScanUtil.setClientVersion(scan, MetaDataProtocol.PHOENIX_VERSION);
    if (aggPlan.getTableRef().getTable().isTransactional() 
            || (table.getType() == PTableType.INDEX && table.isTransactional())) {
        scan.setAttribute(BaseScannerRegionObserver.TX_STATE, txState);
    }
    if (ptr.getLength() > 0) {
        byte[] uuidValue = ServerCacheClient.generateId();
        scan.setAttribute(PhoenixIndexCodec.INDEX_UUID, uuidValue);
        scan.setAttribute(PhoenixIndexCodec.INDEX_PROTO_MD, ptr.get());
    }
    ResultIterator iterator = aggPlan.iterator();
    try {
        Tuple row = iterator.next();
        final long mutationCount = (Long) aggProjector.getColumnProjector(0).getValue(row,
                PLong.INSTANCE, ptr);
        return new MutationState(maxSize, maxSizeBytes, connection) {
            @Override
            public long getUpdateCount() {
                return mutationCount;
            }
        };
    } finally {
        iterator.close();
    }

}
 
Example 5
Source File: DeleteCompiler.java    From phoenix with Apache License 2.0 5 votes vote down vote up
@Override
public MutationState execute() throws SQLException {
    // TODO: share this block of code with UPSERT SELECT
    ImmutableBytesWritable ptr = context.getTempPtr();
    PTable table = dataPlan.getTableRef().getTable();
    table.getIndexMaintainers(ptr, context.getConnection());
    byte[] txState = table.isTransactional() ? connection.getMutationState().encodeTransaction() : ByteUtil.EMPTY_BYTE_ARRAY;
    ServerCache cache = null;
    try {
        if (ptr.getLength() > 0) {
            byte[] uuidValue = ServerCacheClient.generateId();
            context.getScan().setAttribute(PhoenixIndexCodec.INDEX_UUID, uuidValue);
            context.getScan().setAttribute(PhoenixIndexCodec.INDEX_PROTO_MD, ptr.get());
            context.getScan().setAttribute(BaseScannerRegionObserver.TX_STATE, txState);
            ScanUtil.setClientVersion(context.getScan(), MetaDataProtocol.PHOENIX_VERSION);
        }
        ResultIterator iterator = aggPlan.iterator();
        try {
            Tuple row = iterator.next();
            final long mutationCount = (Long) projector.getColumnProjector(0).getValue(row, PLong.INSTANCE, ptr);
            return new MutationState(maxSize, maxSizeBytes, connection) {
                @Override
                public long getUpdateCount() {
                    return mutationCount;
                }
            };
        } finally {
            iterator.close();
        }
    } finally {
        if (cache != null) {
            cache.close();
        }
    }
}
 
Example 6
Source File: IndexMaintainer.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static void serializeServerMaintainedIndexes(PTable dataTable, ImmutableBytesWritable ptr,
        List<PTable> indexes, PhoenixConnection connection) {
    Iterator<PTable> indexesItr = Collections.emptyListIterator();
    boolean onlyLocalIndexes = dataTable.isImmutableRows() || dataTable.isTransactional();
    if (onlyLocalIndexes) {
        if (!dataTable.isTransactional()
                || !dataTable.getTransactionProvider().getTransactionProvider().isUnsupported(Feature.MAINTAIN_LOCAL_INDEX_ON_SERVER)) {
            indexesItr = maintainedLocalIndexes(indexes.iterator());
        }
    } else {
        indexesItr = maintainedIndexes(indexes.iterator());
    }

    serialize(dataTable, ptr, Lists.newArrayList(indexesItr), connection);
}
 
Example 7
Source File: IndexUpgradeTool.java    From phoenix with Apache License 2.0 5 votes vote down vote up
private boolean extractTablesAndIndexes(PhoenixConnection conn) {
    String [] tables = inputTables.trim().split(",");
    PTable dataTable = null;
    try {
        for (String tableName : tables) {
            HashSet<String> physicalIndexes = new HashSet<>();
            dataTable = PhoenixRuntime.getTableNoCache(conn, tableName);
            String physicalTableName = dataTable.getPhysicalName().getString();
            if (!dataTable.isTransactional() && dataTable.getType().equals(PTableType.TABLE)) {
                for (PTable indexTable : dataTable.getIndexes()) {
                    if (indexTable.getIndexType().equals(PTable.IndexType.GLOBAL)) {
                        String physicalIndexName = indexTable.getPhysicalName().getString();
                        physicalIndexes.add(physicalIndexName);
                    }
                }
                if (MetaDataUtil.hasViewIndexTable(conn, dataTable.getPhysicalName())) {
                    String viewIndexPhysicalName = MetaDataUtil
                            .getViewIndexPhysicalName(physicalTableName);
                    physicalIndexes.add(viewIndexPhysicalName);
                }
                //for upgrade or rollback
                tablesAndIndexes.put(physicalTableName, physicalIndexes);
            } else {
                LOGGER.info("Skipping Table " + tableName + " because it is " +
                        (dataTable.isTransactional() ? "transactional" : "not a data table"));
            }
        }
        return true;
    } catch (SQLException e) {
        LOGGER.severe("Failed to find list of indexes "+e);
        if (dataTable == null) {
            LOGGER.severe("Unable to find the provided data table");
        }
        return false;
    }
}
 
Example 8
Source File: MutationState.java    From phoenix with Apache License 2.0 5 votes vote down vote up
/**
 * Commit a write fence when creating an index so that we can detect when a data table transaction is started before
 * the create index but completes after it. In this case, we need to rerun the data table transaction after the
 * index creation so that the index rows are generated. See TEPHRA-157 for more information.
 * 
 * @param dataTable
 *            the data table upon which an index is being added
 * @throws SQLException
 */
public void commitDDLFence(PTable dataTable) throws SQLException {
    if (dataTable.isTransactional()) {
        try {
            phoenixTransactionContext.commitDDLFence(dataTable);
        } finally {
            // The client expects a transaction to be in progress on the txContext while the
            // VisibilityFence.prepareWait() starts a new tx and finishes/aborts it. After it's
            // finished, we start a new one here.
            // TODO: seems like an autonomous tx capability in Tephra would be useful here.
            phoenixTransactionContext.begin();
        }
    }
}
 
Example 9
Source File: MutationState.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public Table getHTable(PTable table) throws SQLException {
    Table htable = this.getConnection().getQueryServices().getTable(table.getPhysicalName().getBytes());
    if (table.isTransactional() && phoenixTransactionContext.isTransactionRunning()) {
        // We're only using this table for reading, so we want it wrapped even if it's an index
        htable = phoenixTransactionContext.getTransactionalTable(htable, table.isImmutableRows() || table.getType() == PTableType.INDEX);
    }
    return htable;
}
 
Example 10
Source File: EncodedColumnsUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static boolean useEncodedQualifierListOptimization(PTable table, Scan scan) {
    /*
     * HBase doesn't allow raw scans to have columns set. And we need columns to be set
     * explicitly on the scan to use this optimization.
     *
     * Disabling this optimization for tables with more than one column family.
     * See PHOENIX-3890.
     */
    return !scan.isRaw() && table.getColumnFamilies().size() <= 1 && table.getImmutableStorageScheme() != null
            && table.getImmutableStorageScheme() == ImmutableStorageScheme.ONE_CELL_PER_COLUMN
            && usesEncodedColumnNames(table) && !table.isTransactional()
            && !ScanUtil.hasDynamicColumns(table);
}
 
Example 11
Source File: IndexUtil.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static List<PTable> getClientMaintainedIndexes(PTable table) {
    Iterator<PTable> indexIterator = // Only maintain tables with immutable rows through this client-side mechanism
            (table.isTransactional() && table.getTransactionProvider().getTransactionProvider().isUnsupported(Feature.MAINTAIN_LOCAL_INDEX_ON_SERVER)) ?
                     IndexMaintainer.maintainedIndexes(table.getIndexes().iterator()) :
                         (table.isImmutableRows() || table.isTransactional()) ?
                            IndexMaintainer.maintainedGlobalIndexes(table.getIndexes().iterator()) :
                                Collections.<PTable>emptyIterator();
    return Lists.newArrayList(indexIterator);
}
 
Example 12
Source File: TestUtil.java    From phoenix with Apache License 2.0 4 votes vote down vote up
/**
 * Runs a major compaction, and then waits until the compaction is complete before returning.
 *
 * @param tableName name of the table to be compacted
 */
public static void doMajorCompaction(Connection conn, String tableName) throws Exception {

    tableName = SchemaUtil.normalizeIdentifier(tableName);

    // We simply write a marker row, request a major compaction, and then wait until the marker
    // row is gone
    PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
    PTable table = pconn.getTable(new PTableKey(pconn.getTenantId(), tableName));
    ConnectionQueryServices services = conn.unwrap(PhoenixConnection.class).getQueryServices();
    MutationState mutationState = pconn.getMutationState();
    if (table.isTransactional()) {
        mutationState.startTransaction(table.getTransactionProvider());
    }
    try (Table htable = mutationState.getHTable(table)) {
        byte[] markerRowKey = Bytes.toBytes("TO_DELETE");
       
        Put put = new Put(markerRowKey);
        put.addColumn(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
        htable.put(put);
        Delete delete = new Delete(markerRowKey);
        delete.addColumn(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
        htable.delete(delete);
        htable.close();
        if (table.isTransactional()) {
            mutationState.commit();
        }
    
        Admin hbaseAdmin = services.getAdmin();
        hbaseAdmin.flush(TableName.valueOf(tableName));
        hbaseAdmin.majorCompact(TableName.valueOf(tableName));
        hbaseAdmin.close();
    
        boolean compactionDone = false;
        while (!compactionDone) {
            Thread.sleep(6000L);
            Scan scan = new Scan();
            scan.setStartRow(markerRowKey);
            scan.setStopRow(Bytes.add(markerRowKey, new byte[] { 0 }));
            scan.setRaw(true);
    
            try (Table htableForRawScan = services.getTable(Bytes.toBytes(tableName))) {
                ResultScanner scanner = htableForRawScan.getScanner(scan);
                List<Result> results = Lists.newArrayList(scanner);
                LOGGER.info("Results: " + results);
                compactionDone = results.isEmpty();
                scanner.close();
            }
            LOGGER.info("Compaction done: " + compactionDone);
            
            // need to run compaction after the next txn snapshot has been written so that compaction can remove deleted rows
            if (!compactionDone && table.isTransactional()) {
                hbaseAdmin = services.getAdmin();
                hbaseAdmin.flush(TableName.valueOf(tableName));
                hbaseAdmin.majorCompact(TableName.valueOf(tableName));
                hbaseAdmin.close();
            }
        }
    }
}
 
Example 13
Source File: TransactionUtil.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static long getResolvedTimestamp(PhoenixConnection connection, MetaDataMutationResult result) {
	PTable table = result.getTable();
	MutationState mutationState = connection.getMutationState();
	boolean txInProgress = table != null && table.isTransactional() && mutationState.isTransactionStarted();
	return  txInProgress ? convertToMilliseconds(mutationState.getInitialWritePointer()) : result.getMutationTime();
}
 
Example 14
Source File: TransactionUtil.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static long getResolvedTime(PhoenixConnection connection, MetaDataMutationResult result) {
	PTable table = result.getTable();
	boolean isTransactional = table!=null && table.isTransactional();
	return getResolvedTimestamp(connection, isTransactional, result.getMutationTime());
}
 
Example 15
Source File: IndexUtil.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static void setScanAttributesForIndexReadRepair(Scan scan, PTable table, PhoenixConnection phoenixConnection) throws SQLException {
    if (table.isTransactional() || table.getType() != PTableType.INDEX) {
        return;
    }
    PTable indexTable = table;
    if (indexTable.getIndexType() != PTable.IndexType.GLOBAL) {
        return;
    }
    String schemaName = indexTable.getParentSchemaName().getString();
    String tableName = indexTable.getParentTableName().getString();
    PTable dataTable;
    try {
        dataTable = PhoenixRuntime.getTable(phoenixConnection, SchemaUtil.getTableName(schemaName, tableName));
    } catch (TableNotFoundException e) {
        // This index table must be being deleted. No need to set the scan attributes
        return;
    }
    // MetaDataClient modifies the index table name for view indexes if the parent view of an index has a child
    // view. This, we need to recreate a PTable object with the correct table name for the rest of this code to work
    if (indexTable.getViewIndexId() != null && indexTable.getName().getString().contains(QueryConstants.CHILD_VIEW_INDEX_NAME_SEPARATOR)) {
        int lastIndexOf = indexTable.getName().getString().lastIndexOf(QueryConstants.CHILD_VIEW_INDEX_NAME_SEPARATOR);
        String indexName = indexTable.getName().getString().substring(lastIndexOf + 1);
        indexTable = PhoenixRuntime.getTable(phoenixConnection, indexName);
    }
    if (!dataTable.getIndexes().contains(indexTable)) {
        return;
    }
    if (scan.getAttribute(PhoenixIndexCodec.INDEX_PROTO_MD) == null) {
        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
        IndexMaintainer.serialize(dataTable, ptr, Collections.singletonList(indexTable), phoenixConnection);
        scan.setAttribute(PhoenixIndexCodec.INDEX_PROTO_MD, ByteUtil.copyKeyBytesIfNecessary(ptr));
    }
    scan.setAttribute(BaseScannerRegionObserver.CHECK_VERIFY_COLUMN, TRUE_BYTES);
    scan.setAttribute(BaseScannerRegionObserver.PHYSICAL_DATA_TABLE_NAME, dataTable.getPhysicalName().getBytes());
    IndexMaintainer indexMaintainer = indexTable.getIndexMaintainer(dataTable, phoenixConnection);
    byte[] emptyCF = indexMaintainer.getEmptyKeyValueFamily().copyBytesIfNecessary();
    byte[] emptyCQ = indexMaintainer.getEmptyKeyValueQualifier();
    scan.setAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_FAMILY_NAME, emptyCF);
    scan.setAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER_NAME, emptyCQ);
    if (scan.getAttribute(BaseScannerRegionObserver.VIEW_CONSTANTS) == null) {
        BaseQueryPlan.serializeViewConstantsIntoScan(scan, dataTable);
    }
    addEmptyColumnToScan(scan, emptyCF, emptyCQ);
}
 
Example 16
Source File: MutationState.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private void send(Iterator<TableRef> tableRefIterator) throws SQLException {
    int i = 0;
    long[] serverTimeStamps = null;
    boolean sendAll = false;
    if (tableRefIterator == null) {
        serverTimeStamps = validateAll();
        tableRefIterator = mutations.keySet().iterator();
        sendAll = true;
    }

    MultiRowMutationState multiRowMutationState;
    Map<TableInfo, List<Mutation>> physicalTableMutationMap = Maps.newLinkedHashMap();
    // add tracing for this operation
    try (TraceScope trace = Tracing.startNewSpan(connection, "Committing mutations to tables")) {
        Span span = trace.getSpan();
        ImmutableBytesWritable indexMetaDataPtr = new ImmutableBytesWritable();
        while (tableRefIterator.hasNext()) {
            // at this point we are going through mutations for each table
            final TableRef tableRef = tableRefIterator.next();
            multiRowMutationState = mutations.get(tableRef);
            if (multiRowMutationState == null || multiRowMutationState.isEmpty()) {
                continue;
            }
            // Validate as we go if transactional since we can undo if a problem occurs (which is unlikely)
            long
                    serverTimestamp =
                    serverTimeStamps == null ?
                            validateAndGetServerTimestamp(tableRef, multiRowMutationState) :
                            serverTimeStamps[i++];
            final PTable table = tableRef.getTable();
            Long scn = connection.getSCN();
            long mutationTimestamp = scn == null ?
                (table.isTransactional() == true ? HConstants.LATEST_TIMESTAMP : EnvironmentEdgeManager.currentTimeMillis())
                    : scn;
            Iterator<Pair<PTable, List<Mutation>>>
                    mutationsIterator =
                    addRowMutations(tableRef, multiRowMutationState, mutationTimestamp,
                            serverTimestamp, false, sendAll);
            // build map from physical table to mutation list
            boolean isDataTable = true;
            while (mutationsIterator.hasNext()) {
                Pair<PTable, List<Mutation>> pair = mutationsIterator.next();
                PTable logicalTable = pair.getFirst();
                List<Mutation> mutationList = pair.getSecond();

                TableInfo tableInfo = new TableInfo(isDataTable, logicalTable.getPhysicalName(),
                        tableRef, logicalTable);

                List<Mutation>
                        oldMutationList =
                        physicalTableMutationMap.put(tableInfo, mutationList);
                if (oldMutationList != null) mutationList.addAll(0, oldMutationList);
                isDataTable = false;
            }
            // For transactions, track the statement indexes as we send data
            // over because our CommitException should include all statements
            // involved in the transaction since none of them would have been
            // committed in the event of a failure.
            if (table.isTransactional()) {
                addUncommittedStatementIndexes(multiRowMutationState.values());
                if (txMutations.isEmpty()) {
                    txMutations = Maps.newHashMapWithExpectedSize(mutations.size());
                }
                // Keep all mutations we've encountered until a commit or rollback.
                // This is not ideal, but there's not good way to get the values back
                // in the event that we need to replay the commit.
                // Copy TableRef so we have the original PTable and know when the
                // indexes have changed.
                joinMutationState(new TableRef(tableRef), multiRowMutationState, txMutations);
            }
        }

        Map<TableInfo, List<Mutation>> unverifiedIndexMutations = new LinkedHashMap<>();
        Map<TableInfo, List<Mutation>> verifiedOrDeletedIndexMutations = new LinkedHashMap<>();
        filterIndexCheckerMutations(physicalTableMutationMap, unverifiedIndexMutations,
                verifiedOrDeletedIndexMutations);

        // Phase 1: Send index mutations with the empty column value = "unverified"
        sendMutations(unverifiedIndexMutations.entrySet().iterator(), span, indexMetaDataPtr, false);

        // Phase 2: Send data table and other indexes
        sendMutations(physicalTableMutationMap.entrySet().iterator(), span, indexMetaDataPtr, false);

        // Phase 3: Send put index mutations with the empty column value = "verified" and/or delete index mutations
        try {
            sendMutations(verifiedOrDeletedIndexMutations.entrySet().iterator(), span, indexMetaDataPtr, true);
        } catch (SQLException ex) {
            LOGGER.warn(
                    "Ignoring exception that happened during setting index verified value to verified=TRUE ",
                    ex);
        }
    }
}
 
Example 17
Source File: MutationState.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private Iterator<Pair<PTable, List<Mutation>>> addRowMutations(final TableRef tableRef,
        final MultiRowMutationState values, final long mutationTimestamp, final long serverTimestamp,
        boolean includeAllIndexes, final boolean sendAll) {
    final PTable table = tableRef.getTable();
    final List<PTable> indexList = includeAllIndexes ? 
            Lists.newArrayList(IndexMaintainer.maintainedIndexes(table.getIndexes().iterator())) : 
                IndexUtil.getClientMaintainedIndexes(table);
    final Iterator<PTable> indexes = indexList.iterator();
    final List<Mutation> mutationList = Lists.newArrayListWithExpectedSize(values.size());
    final List<Mutation> mutationsPertainingToIndex = indexes.hasNext() ? Lists
            .newArrayListWithExpectedSize(values.size()) : null;
    generateMutations(tableRef, mutationTimestamp, serverTimestamp, values, mutationList,
            mutationsPertainingToIndex);
    return new Iterator<Pair<PTable, List<Mutation>>>() {
        boolean isFirst = true;
        Map<byte[], List<Mutation>> indexMutationsMap = null;

        @Override
        public boolean hasNext() {
            return isFirst || indexes.hasNext();
        }

        @Override
        public Pair<PTable, List<Mutation>> next() {
            if (isFirst) {
                isFirst = false;
                return new Pair<>(table, mutationList);
            }

            PTable index = indexes.next();

            List<Mutation> indexMutations = null;
            try {
                if (!mutationsPertainingToIndex.isEmpty()) {
                    if (table.isTransactional()) {
                        if (indexMutationsMap == null) {
                            PhoenixTxIndexMutationGenerator generator = PhoenixTxIndexMutationGenerator.newGenerator(connection, table,
                                    indexList, mutationsPertainingToIndex.get(0).getAttributesMap());
                            try (Table htable = connection.getQueryServices().getTable(
                                    table.getPhysicalName().getBytes())) {
                                Collection<Pair<Mutation, byte[]>> allMutations = generator.getIndexUpdates(htable,
                                        mutationsPertainingToIndex.iterator());
                                indexMutationsMap = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
                                for (Pair<Mutation, byte[]> mutation : allMutations) {
                                    List<Mutation> mutations = indexMutationsMap.get(mutation.getSecond());
                                    if (mutations == null) {
                                        mutations = Lists.newArrayList();
                                        indexMutationsMap.put(mutation.getSecond(), mutations);
                                    }
                                    mutations.add(mutation.getFirst());
                                }
                            }
                        }
                        indexMutations = indexMutationsMap.get(index.getPhysicalName().getBytes());
                    } else {
                        indexMutations = IndexUtil.generateIndexData(table, index, values,
                                mutationsPertainingToIndex, connection.getKeyValueBuilder(), connection);
                    }
                }

                // we may also have to include delete mutations for immutable tables if we are not processing all
                // the tables in the mutations map
                if (!sendAll) {
                    TableRef key = new TableRef(index);
                    MultiRowMutationState multiRowMutationState = mutations.remove(key);
                    if (multiRowMutationState != null) {
                        final List<Mutation> deleteMutations = Lists.newArrayList();
                        generateMutations(key, mutationTimestamp, serverTimestamp, multiRowMutationState, deleteMutations, null);
                        if (indexMutations == null) {
                            indexMutations = deleteMutations;
                        } else {
                            indexMutations.addAll(deleteMutations);
                        }
                    }
                }
            } catch (SQLException | IOException e) {
                throw new IllegalDataException(e);
            }
            return new Pair<PTable, List<Mutation>>(index,
                    indexMutations == null ? Collections.<Mutation> emptyList()
                            : indexMutations);
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

    };
}
 
Example 18
Source File: IndexTool.java    From phoenix with Apache License 2.0 4 votes vote down vote up
private static boolean isFeatureApplicable(PTable dataTable, boolean isLocalIndexBuild) {
    if (isLocalIndexBuild || !dataTable.isTransactional()) {
        return true;
    }
    return false;
}
 
Example 19
Source File: IndexMetaDataCacheClient.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static ServerCache setMetaDataOnMutations(PhoenixConnection connection, PTable table, List<? extends Mutation> mutations,
        ImmutableBytesWritable indexMetaDataPtr) throws SQLException {
    final byte[] tenantIdBytes;
    if (table.isMultiTenant()) {
        tenantIdBytes = connection.getTenantId() == null ? null : ScanUtil.getTenantIdBytes(
                table.getRowKeySchema(), table.getBucketNum() != null, connection.getTenantId(),
                table.getViewIndexId() != null);
    } else {
        tenantIdBytes = connection.getTenantId() == null ? null : connection.getTenantId().getBytes();
    }
    ServerCache cache = null;
    byte[] attribValue = null;
    byte[] uuidValue = null;
    byte[] txState = ByteUtil.EMPTY_BYTE_ARRAY;
    if (table.isTransactional()) {
        txState = connection.getMutationState().encodeTransaction();
    }
    boolean hasIndexMetaData = indexMetaDataPtr.getLength() > 0;
    if (hasIndexMetaData) {
        if (useIndexMetadataCache(connection, mutations, indexMetaDataPtr.getLength() + txState.length)) {
            IndexMetaDataCacheClient client = new IndexMetaDataCacheClient(connection, table);
            cache = client.addIndexMetadataCache(mutations, indexMetaDataPtr, txState);
            uuidValue = cache.getId();
        } else {
            attribValue = ByteUtil.copyKeyBytesIfNecessary(indexMetaDataPtr);
            uuidValue = ServerCacheClient.generateId();
        }
    } else if (txState.length == 0) { return null; }
    // Either set the UUID to be able to access the index metadata from the cache
    // or set the index metadata directly on the Mutation
    for (Mutation mutation : mutations) {
        if (connection.getTenantId() != null) {
            mutation.setAttribute(PhoenixRuntime.TENANT_ID_ATTRIB, tenantIdBytes);
        }
        mutation.setAttribute(PhoenixIndexCodec.INDEX_UUID, uuidValue);
        if (attribValue != null) {
            mutation.setAttribute(PhoenixIndexCodec.INDEX_PROTO_MD, attribValue);
            mutation.setAttribute(BaseScannerRegionObserver.CLIENT_VERSION,
                    Bytes.toBytes(MetaDataProtocol.PHOENIX_VERSION));
            if (txState.length > 0) {
                mutation.setAttribute(BaseScannerRegionObserver.TX_STATE, txState);
            }
        } else if (!hasIndexMetaData && txState.length > 0) {
            mutation.setAttribute(BaseScannerRegionObserver.TX_STATE, txState);
        }
    }
    return cache;
}
 
Example 20
Source File: PostLocalIndexDDLCompiler.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public MutationPlan compile(PTable index) throws SQLException {
try (final PhoenixStatement statement = new PhoenixStatement(connection)) {
          String query = "SELECT count(*) FROM " + tableName;
          final QueryPlan plan = statement.compileQuery(query);
          TableRef tableRef = plan.getTableRef();
          Scan scan = plan.getContext().getScan();
          ImmutableBytesWritable ptr = new ImmutableBytesWritable();
          final PTable dataTable = tableRef.getTable();
          List<PTable> indexes = Lists.newArrayListWithExpectedSize(1);
          for (PTable indexTable : dataTable.getIndexes()) {
              if (indexTable.getKey().equals(index.getKey())) {
                  index = indexTable;
                  break;
              }
          }
          // Only build newly created index.
          indexes.add(index);
          IndexMaintainer.serialize(dataTable, ptr, indexes, plan.getContext().getConnection());
          // Set attribute on scan that UngroupedAggregateRegionObserver will switch on.
          // We'll detect that this attribute was set the server-side and write the index
          // rows per region as a result. The value of the attribute will be our persisted
          // index maintainers.
          // Define the LOCAL_INDEX_BUILD as a new static in BaseScannerRegionObserver
          scan.setAttribute(BaseScannerRegionObserver.LOCAL_INDEX_BUILD_PROTO, ByteUtil.copyKeyBytesIfNecessary(ptr));
          // By default, we'd use a FirstKeyOnly filter as nothing else needs to be projected for count(*).
          // However, in this case, we need to project all of the data columns that contribute to the index.
          IndexMaintainer indexMaintainer = index.getIndexMaintainer(dataTable, connection);
          for (ColumnReference columnRef : indexMaintainer.getAllColumns()) {
              if (index.getImmutableStorageScheme() == ImmutableStorageScheme.SINGLE_CELL_ARRAY_WITH_OFFSETS) {
                  scan.addFamily(columnRef.getFamily());
              } else {
                  scan.addColumn(columnRef.getFamily(), columnRef.getQualifier());
              }
          }
          if (dataTable.isTransactional()) {
              scan.setAttribute(BaseScannerRegionObserver.TX_STATE, connection.getMutationState().encodeTransaction());
          }

          // Go through MutationPlan abstraction so that we can create local indexes
          // with a connectionless connection (which makes testing easier).
          return new PostLocalIndexDDLMutationPlan(plan, dataTable);
  }
}