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

The following examples show how to use org.apache.phoenix.schema.PTable#getIndexMaintainer() . 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: PhoenixTxIndexMutationGenerator.java    From phoenix with Apache License 2.0 5 votes vote down vote up
public static PhoenixTxIndexMutationGenerator newGenerator(final PhoenixConnection connection, PTable table, List<PTable> indexes,
        Map<String, byte[]> attributes) {
    final List<IndexMaintainer> indexMaintainers = Lists.newArrayListWithExpectedSize(indexes.size());
    for (PTable index : indexes) {
        IndexMaintainer maintainer = index.getIndexMaintainer(table, connection);
        indexMaintainers.add(maintainer);
    }
    IndexMetaDataCache indexMetaDataCache = new IndexMetaDataCache() {

        @Override
        public void close() throws IOException {}

        @Override
        public List<IndexMaintainer> getIndexMaintainers() {
            return indexMaintainers;
        }

        @Override
        public PhoenixTransactionContext getTransactionContext() {
            PhoenixTransactionContext context = connection.getMutationState().getPhoenixTransactionContext();
            return context.newTransactionContext(context, true);
        }

        @Override
        public int getClientVersion() {
            return MetaDataProtocol.PHOENIX_VERSION;
        }

    };
    try {
        PhoenixIndexMetaData indexMetaData = new PhoenixIndexMetaData(indexMetaDataCache, attributes);
        return new PhoenixTxIndexMutationGenerator(connection.getQueryServices(),connection.getQueryServices().getConfiguration(), indexMetaData,
                table.getPhysicalName().getBytes(), null, null);
    } catch (IOException e) {
        throw new RuntimeException(e); // Impossible
    }
}
 
Example 2
Source File: PrepareIndexMutationsForRebuildTest.java    From phoenix with Apache License 2.0 5 votes vote down vote up
/**
 * Get the index maintainer and phoenix table definition of data table.
 * @param tableName
 * @param indexName
 * @param columns
 * @param indexColumns
 * @param pk
 * @param includeColumns
 * @return
 * @throws Exception
 */
private SetupInfo setup(String tableName,
                        String indexName,
                        String columns,
                        String indexColumns,
                        String pk,
                        String includeColumns) throws Exception {
    try(Connection conn = DriverManager.getConnection(getUrl())) {

        String fullTableName = SchemaUtil.getTableName(SchemaUtil.normalizeIdentifier(""), SchemaUtil.normalizeIdentifier(tableName));
        String fullIndexName = SchemaUtil.getTableName(SchemaUtil.normalizeIdentifier(""), SchemaUtil.normalizeIdentifier(indexName));

        // construct the data table and index based from the parameters
        String str1 = String.format("CREATE TABLE %1$s (%2$s CONSTRAINT pk PRIMARY KEY (%3$s)) COLUMN_ENCODED_BYTES=0",
                fullTableName,
                columns,
                pk);
        conn.createStatement().execute(str1);

        String str2 = String.format("CREATE INDEX %1$s ON %2$s (%3$s)",
                fullIndexName,
                fullTableName,
                indexColumns);
        if (!includeColumns.isEmpty())
            str2 += " INCLUDE (" + includeColumns + ")";
        conn.createStatement().execute(str2);

        // Get the data table, index table and index maintainer reference from the client's ConnectionQueryServiceImpl
        // In this way, we don't need to setup a local cluster.
        PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
        PTable pIndexTable = pconn.getTable(new PTableKey(pconn.getTenantId(), fullIndexName));
        PTable pDataTable = pconn.getTable(new PTableKey(pconn.getTenantId(), fullTableName));
        IndexMaintainer im = pIndexTable.getIndexMaintainer(pDataTable, pconn);

        SetupInfo info = new SetupInfo();
        info.indexMaintainer = im;
        info.pDataTable = pDataTable;
        return info;
    }
}
 
Example 3
Source File: ServerBuildIndexCompiler.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;
        this.plan = statement.compileQuery(query);
        TableRef tableRef = plan.getTableRef();
        Scan scan = plan.getContext().getScan();
        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
        dataTable = tableRef.getTable();
        if (index.getIndexType() == PTable.IndexType.GLOBAL &&  dataTable.isTransactional()) {
            throw new IllegalArgumentException(
                    "ServerBuildIndexCompiler does not support global indexes on transactional tables");
        }
        IndexMaintainer indexMaintainer = index.getIndexMaintainer(dataTable, connection);
        // 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.
        for (ColumnReference columnRef : indexMaintainer.getAllColumns()) {
            if (index.getImmutableStorageScheme() == PTable.ImmutableStorageScheme.SINGLE_CELL_ARRAY_WITH_OFFSETS) {
                scan.addFamily(columnRef.getFamily());
            } else {
                scan.addColumn(columnRef.getFamily(), columnRef.getQualifier());
            }
        }
        IndexMaintainer.serialize(dataTable, ptr, Collections.singletonList(index), plan.getContext().getConnection());
        // Set the scan attributes that UngroupedAggregateRegionObserver will switch on.
        // For local indexes, the BaseScannerRegionObserver.LOCAL_INDEX_BUILD_PROTO attribute, and
        // for global indexes PhoenixIndexCodec.INDEX_PROTO_MD attribute is set to the serialized form of index
        // metadata to build index rows from data table rows. For global indexes, we also need to set (1) the
        // BaseScannerRegionObserver.REBUILD_INDEXES attribute in order to signal UngroupedAggregateRegionObserver
        // that this scan is for building global indexes and (2) the MetaDataProtocol.PHOENIX_VERSION attribute
        // that will be passed as a mutation attribute for the scanned mutations that will be applied on
        // the index table possibly remotely
        if (index.getIndexType() == PTable.IndexType.LOCAL) {
            scan.setAttribute(BaseScannerRegionObserver.LOCAL_INDEX_BUILD_PROTO, ByteUtil.copyKeyBytesIfNecessary(ptr));
        } else {
            scan.setAttribute(PhoenixIndexCodec.INDEX_PROTO_MD, ByteUtil.copyKeyBytesIfNecessary(ptr));
            scan.setAttribute(BaseScannerRegionObserver.REBUILD_INDEXES, TRUE_BYTES);
            ScanUtil.setClientVersion(scan, MetaDataProtocol.PHOENIX_VERSION);
            scan.setAttribute(BaseScannerRegionObserver.INDEX_REBUILD_PAGING, TRUE_BYTES);
            // Serialize page row size only if we're overriding, else use server side value
            String rebuildPageRowSize =
                    connection.getQueryServices().getProps()
                            .get(QueryServices.INDEX_REBUILD_PAGE_SIZE_IN_ROWS);
            if (rebuildPageRowSize != null) {
                scan.setAttribute(BaseScannerRegionObserver.INDEX_REBUILD_PAGE_ROWS,
                    Bytes.toBytes(Long.valueOf(rebuildPageRowSize)));
            }
            BaseQueryPlan.serializeViewConstantsIntoScan(scan, dataTable);
            addEmptyColumnToScan(scan, indexMaintainer.getDataEmptyKeyValueCF(), indexMaintainer.getEmptyKeyValueQualifier());
        }
        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 RowCountMutationPlan(plan.getContext(), PhoenixStatement.Operation.UPSERT);
    }
}
 
Example 4
Source File: UpsertCompiler.java    From phoenix with Apache License 2.0 4 votes vote down vote up
public static MutationState upsertSelect(StatementContext childContext, TableRef tableRef,
        RowProjector projector, ResultIterator iterator, int[] columnIndexes,
        int[] pkSlotIndexes, boolean useServerTimestamp,
        boolean prefixSysColValues) throws SQLException {
    PhoenixStatement statement = childContext.getStatement();
    PhoenixConnection connection = statement.getConnection();
    ConnectionQueryServices services = connection.getQueryServices();
    int maxSize = services.getProps().getInt(QueryServices.MAX_MUTATION_SIZE_ATTRIB,
            QueryServicesOptions.DEFAULT_MAX_MUTATION_SIZE);
    int maxSizeBytes =
            services.getProps().getInt(QueryServices.MAX_MUTATION_SIZE_BYTES_ATTRIB,
                QueryServicesOptions.DEFAULT_MAX_MUTATION_SIZE_BYTES);
    int batchSize = Math.min(connection.getMutateBatchSize(), maxSize);
    // we automatically flush the mutations when either auto commit is enabled, or
    // the target table is transactional (in that case changes are not visible until we commit)
    final boolean autoFlush = connection.getAutoCommit() || tableRef.getTable().isTransactional();
    int sizeOffset = 0;
    int numSplColumns =
            (tableRef.getTable().isMultiTenant() ? 1 : 0)
                    + (tableRef.getTable().getViewIndexId() != null ? 1 : 0);
    byte[][] values = new byte[columnIndexes.length + numSplColumns][];
    if(prefixSysColValues) {
        int i = 0;
        if(tableRef.getTable().isMultiTenant()) {
            values[i++] = connection.getTenantId().getBytes();
        }
        if(tableRef.getTable().getViewIndexId() != null) {
            values[i++] = PSmallint.INSTANCE.toBytes(tableRef.getTable().getViewIndexId());
        }
    }
    int rowCount = 0;
    MultiRowMutationState mutation = new MultiRowMutationState(batchSize);
    PTable table = tableRef.getTable();
    IndexMaintainer indexMaintainer = null;
    byte[][] viewConstants = null;
    if (table.getIndexType() == IndexType.LOCAL) {
        PTable parentTable =
                statement
                        .getConnection()
                        .getMetaDataCache()
                        .getTableRef(
                            new PTableKey(statement.getConnection().getTenantId(), table
                                    .getParentName().getString())).getTable();
        indexMaintainer = table.getIndexMaintainer(parentTable, connection);
        viewConstants = IndexUtil.getViewConstants(parentTable);
    }
    try (ResultSet rs = new PhoenixResultSet(iterator, projector, childContext)) {
        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
        while (rs.next()) {
            for (int i = 0, j = numSplColumns; j < values.length; j++, i++) {
                PColumn column = table.getColumns().get(columnIndexes[i]);
                byte[] bytes = rs.getBytes(i + 1);
                ptr.set(bytes == null ? ByteUtil.EMPTY_BYTE_ARRAY : bytes);
                Object value = rs.getObject(i + 1);
                int rsPrecision = rs.getMetaData().getPrecision(i + 1);
                Integer precision = rsPrecision == 0 ? null : rsPrecision;
                int rsScale = rs.getMetaData().getScale(i + 1);
                Integer scale = rsScale == 0 ? null : rsScale;
                // We are guaranteed that the two column will have compatible types,
                // as we checked that before.
                if (!column.getDataType().isSizeCompatible(ptr, value, column.getDataType(),
                        SortOrder.getDefault(), precision,
                        scale, column.getMaxLength(), column.getScale())) {
                    throw new SQLExceptionInfo.Builder(
                        SQLExceptionCode.DATA_EXCEEDS_MAX_CAPACITY).setColumnName(
                                column.getName().getString())
                        .setMessage("value=" + column.getDataType()
                                .toStringLiteral(ptr, null)).build()
                        .buildException();
                }
                column.getDataType().coerceBytes(ptr, value, column.getDataType(), 
                        precision, scale, SortOrder.getDefault(), 
                        column.getMaxLength(), column.getScale(), column.getSortOrder(),
                        table.rowKeyOrderOptimizable());
                values[j] = ByteUtil.copyKeyBytesIfNecessary(ptr);
            }
            setValues(values, pkSlotIndexes, columnIndexes, table, mutation, statement,
                    useServerTimestamp, indexMaintainer, viewConstants, null,
                    numSplColumns);
            rowCount++;
            // Commit a batch if auto commit is true and we're at our batch size
            if (autoFlush && rowCount % batchSize == 0) {
                MutationState state = new MutationState(tableRef, mutation, 0,
                        maxSize, maxSizeBytes, connection);
                connection.getMutationState().join(state);
                connection.getMutationState().send();
                mutation.clear();
            }
        }

        if (autoFlush) {
            // If auto commit is true, this last batch will be committed upon return
            sizeOffset = rowCount / batchSize * batchSize;
        }
        return new MutationState(tableRef, mutation, sizeOffset, maxSize,
                maxSizeBytes, connection);
    }
}
 
Example 5
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);
  }
}
 
Example 6
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);
}