Search in sources :

Example 1 with SequenceAllocation

use of org.apache.phoenix.schema.SequenceAllocation in project phoenix by apache.

the class ConnectionlessQueryServicesImpl method incrementSequences.

@Override
public void incrementSequences(List<SequenceAllocation> sequenceAllocations, long timestamp, long[] values, SQLException[] exceptions) throws SQLException {
    int i = 0;
    for (SequenceAllocation sequenceAllocation : sequenceAllocations) {
        SequenceKey key = sequenceAllocation.getSequenceKey();
        SequenceInfo info = sequenceMap.get(key);
        if (info == null) {
            exceptions[i] = new SequenceNotFoundException(key.getSchemaName(), key.getSequenceName());
        } else {
            boolean increaseSeq = info.incrementBy > 0;
            if (info.limitReached) {
                SQLExceptionCode code = increaseSeq ? SQLExceptionCode.SEQUENCE_VAL_REACHED_MAX_VALUE : SQLExceptionCode.SEQUENCE_VAL_REACHED_MIN_VALUE;
                exceptions[i] = new SQLExceptionInfo.Builder(code).build().buildException();
            } else {
                values[i] = info.sequenceValue;
                info.sequenceValue += info.incrementBy * info.cacheSize;
                info.limitReached = SequenceUtil.checkIfLimitReached(info);
                if (info.limitReached && info.cycle) {
                    info.sequenceValue = increaseSeq ? info.minValue : info.maxValue;
                    info.limitReached = false;
                }
            }
        }
        i++;
    }
    i = 0;
    for (SQLException e : exceptions) {
        if (e != null) {
            sequenceMap.remove(sequenceAllocations.get(i).getSequenceKey());
        }
        i++;
    }
}
Also used : SQLExceptionCode(org.apache.phoenix.exception.SQLExceptionCode) SequenceKey(org.apache.phoenix.schema.SequenceKey) SequenceInfo(org.apache.phoenix.schema.SequenceInfo) SQLException(java.sql.SQLException) SequenceNotFoundException(org.apache.phoenix.schema.SequenceNotFoundException) SequenceAllocation(org.apache.phoenix.schema.SequenceAllocation) SQLExceptionInfo(org.apache.phoenix.exception.SQLExceptionInfo)

Example 2 with SequenceAllocation

use of org.apache.phoenix.schema.SequenceAllocation in project phoenix by apache.

the class ConnectionlessQueryServicesImpl method validateSequences.

@Override
public void validateSequences(List<SequenceAllocation> sequenceAllocations, long timestamp, long[] values, SQLException[] exceptions, Sequence.ValueOp action) throws SQLException {
    int i = 0;
    for (SequenceAllocation sequenceAllocation : sequenceAllocations) {
        SequenceInfo info = sequenceMap.get(sequenceAllocation.getSequenceKey());
        if (info == null) {
            exceptions[i] = new SequenceNotFoundException(sequenceAllocation.getSequenceKey().getSchemaName(), sequenceAllocation.getSequenceKey().getSequenceName());
        } else {
            values[i] = info.sequenceValue;
        }
        i++;
    }
}
Also used : SequenceInfo(org.apache.phoenix.schema.SequenceInfo) SequenceNotFoundException(org.apache.phoenix.schema.SequenceNotFoundException) SequenceAllocation(org.apache.phoenix.schema.SequenceAllocation)

Example 3 with SequenceAllocation

use of org.apache.phoenix.schema.SequenceAllocation in project phoenix by apache.

the class ConnectionQueryServicesImpl method incrementSequenceValues.

@SuppressWarnings("deprecation")
private void incrementSequenceValues(List<SequenceAllocation> sequenceAllocations, long timestamp, long[] values, SQLException[] exceptions, Sequence.ValueOp op) throws SQLException {
    List<Sequence> sequences = Lists.newArrayListWithExpectedSize(sequenceAllocations.size());
    for (SequenceAllocation sequenceAllocation : sequenceAllocations) {
        SequenceKey key = sequenceAllocation.getSequenceKey();
        Sequence newSequences = new Sequence(key);
        Sequence sequence = sequenceMap.putIfAbsent(key, newSequences);
        if (sequence == null) {
            sequence = newSequences;
        }
        sequences.add(sequence);
    }
    try {
        for (Sequence sequence : sequences) {
            sequence.getLock().lock();
        }
        // Now that we have all the locks we need, increment the sequences
        List<Increment> incrementBatch = Lists.newArrayListWithExpectedSize(sequences.size());
        List<Sequence> toIncrementList = Lists.newArrayListWithExpectedSize(sequences.size());
        int[] indexes = new int[sequences.size()];
        for (int i = 0; i < sequences.size(); i++) {
            Sequence sequence = sequences.get(i);
            try {
                values[i] = sequence.incrementValue(timestamp, op, sequenceAllocations.get(i).getNumAllocations());
            } catch (EmptySequenceCacheException e) {
                indexes[toIncrementList.size()] = i;
                toIncrementList.add(sequence);
                Increment inc = sequence.newIncrement(timestamp, op, sequenceAllocations.get(i).getNumAllocations());
                incrementBatch.add(inc);
            } catch (SQLException e) {
                exceptions[i] = e;
            }
        }
        if (toIncrementList.isEmpty()) {
            return;
        }
        HTableInterface hTable = this.getTable(SchemaUtil.getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES, this.getProps()).getName());
        Object[] resultObjects = null;
        SQLException sqlE = null;
        try {
            resultObjects = hTable.batch(incrementBatch);
        } catch (IOException e) {
            sqlE = ServerUtil.parseServerException(e);
        } catch (InterruptedException e) {
            // restore the interrupt status
            Thread.currentThread().interrupt();
            sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.INTERRUPTED_EXCEPTION).setRootCause(e).build().buildException();
        } finally {
            try {
                hTable.close();
            } catch (IOException e) {
                if (sqlE == null) {
                    sqlE = ServerUtil.parseServerException(e);
                } else {
                    sqlE.setNextException(ServerUtil.parseServerException(e));
                }
            }
            if (sqlE != null) {
                throw sqlE;
            }
        }
        for (int i = 0; i < resultObjects.length; i++) {
            Sequence sequence = toIncrementList.get(i);
            Result result = (Result) resultObjects[i];
            try {
                long numToAllocate = Bytes.toLong(incrementBatch.get(i).getAttribute(SequenceRegionObserver.NUM_TO_ALLOCATE));
                values[indexes[i]] = sequence.incrementValue(result, op, numToAllocate);
            } catch (SQLException e) {
                exceptions[indexes[i]] = e;
            }
        }
    } finally {
        for (Sequence sequence : sequences) {
            sequence.getLock().unlock();
        }
    }
}
Also used : EmptySequenceCacheException(org.apache.phoenix.schema.EmptySequenceCacheException) SQLException(java.sql.SQLException) Sequence(org.apache.phoenix.schema.Sequence) SequenceAllocation(org.apache.phoenix.schema.SequenceAllocation) IOException(java.io.IOException) PhoenixIOException(org.apache.phoenix.exception.PhoenixIOException) HTableInterface(org.apache.hadoop.hbase.client.HTableInterface) PTinyint(org.apache.phoenix.schema.types.PTinyint) PUnsignedTinyint(org.apache.phoenix.schema.types.PUnsignedTinyint) MultiRowMutationEndpoint(org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint) MetaDataMutationResult(org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult) Result(org.apache.hadoop.hbase.client.Result) SequenceKey(org.apache.phoenix.schema.SequenceKey) Increment(org.apache.hadoop.hbase.client.Increment) SQLExceptionInfo(org.apache.phoenix.exception.SQLExceptionInfo)

Example 4 with SequenceAllocation

use of org.apache.phoenix.schema.SequenceAllocation in project phoenix by apache.

the class MetaDataEndpointImpl method createTable.

@Override
public void createTable(RpcController controller, CreateTableRequest request, RpcCallback<MetaDataResponse> done) {
    MetaDataResponse.Builder builder = MetaDataResponse.newBuilder();
    byte[][] rowKeyMetaData = new byte[3][];
    byte[] schemaName = null;
    byte[] tableName = null;
    try {
        int clientVersion = request.getClientVersion();
        List<Mutation> tableMetadata = ProtobufUtil.getMutations(request);
        MetaDataUtil.getTenantIdAndSchemaAndTableName(tableMetadata, rowKeyMetaData);
        byte[] tenantIdBytes = rowKeyMetaData[PhoenixDatabaseMetaData.TENANT_ID_INDEX];
        schemaName = rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX];
        tableName = rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX];
        boolean isNamespaceMapped = MetaDataUtil.isNameSpaceMapped(tableMetadata, GenericKeyValueBuilder.INSTANCE, new ImmutableBytesWritable());
        final IndexType indexType = MetaDataUtil.getIndexType(tableMetadata, GenericKeyValueBuilder.INSTANCE, new ImmutableBytesWritable());
        byte[] parentSchemaName = null;
        byte[] parentTableName = null;
        PTableType tableType = MetaDataUtil.getTableType(tableMetadata, GenericKeyValueBuilder.INSTANCE, new ImmutableBytesWritable());
        byte[] parentTableKey = null;
        Mutation viewPhysicalTableRow = null;
        Set<TableName> indexes = new HashSet<TableName>();
        ;
        byte[] cPhysicalName = SchemaUtil.getPhysicalHBaseTableName(schemaName, tableName, isNamespaceMapped).getBytes();
        byte[] cParentPhysicalName = null;
        if (tableType == PTableType.VIEW) {
            byte[][] parentSchemaTableNames = new byte[3][];
            byte[][] parentPhysicalSchemaTableNames = new byte[3][];
            /*
                 * For a view, we lock the base physical table row. For a mapped view, there is 
                 * no link present to the physical table. So the viewPhysicalTableRow is null
                 * in that case.
                 */
            viewPhysicalTableRow = getPhysicalTableRowForView(tableMetadata, parentSchemaTableNames, parentPhysicalSchemaTableNames);
            long clientTimeStamp = MetaDataUtil.getClientTimeStamp(tableMetadata);
            if (parentPhysicalSchemaTableNames[2] != null) {
                parentTableKey = SchemaUtil.getTableKey(ByteUtil.EMPTY_BYTE_ARRAY, parentPhysicalSchemaTableNames[1], parentPhysicalSchemaTableNames[2]);
                PTable parentTable = getTable(env, parentTableKey, new ImmutableBytesPtr(parentTableKey), clientTimeStamp, clientTimeStamp, clientVersion);
                if (parentTable == null) {
                    builder.setReturnCode(MetaDataProtos.MutationCode.PARENT_TABLE_NOT_FOUND);
                    builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                    done.run(builder.build());
                    return;
                }
                cParentPhysicalName = parentTable.getPhysicalName().getBytes();
                if (parentSchemaTableNames[2] != null && Bytes.compareTo(parentSchemaTableNames[2], parentPhysicalSchemaTableNames[2]) != 0) {
                    // if view is created on view
                    byte[] parentKey = SchemaUtil.getTableKey(parentSchemaTableNames[0] == null ? ByteUtil.EMPTY_BYTE_ARRAY : parentSchemaTableNames[0], parentSchemaTableNames[1], parentSchemaTableNames[2]);
                    parentTable = getTable(env, parentKey, new ImmutableBytesPtr(parentKey), clientTimeStamp, clientTimeStamp, clientVersion);
                    if (parentTable == null) {
                        // it could be a global view
                        parentKey = SchemaUtil.getTableKey(ByteUtil.EMPTY_BYTE_ARRAY, parentSchemaTableNames[1], parentSchemaTableNames[2]);
                        parentTable = getTable(env, parentKey, new ImmutableBytesPtr(parentKey), clientTimeStamp, clientTimeStamp, clientVersion);
                    }
                }
                if (parentTable == null) {
                    builder.setReturnCode(MetaDataProtos.MutationCode.PARENT_TABLE_NOT_FOUND);
                    builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                    done.run(builder.build());
                    return;
                }
                for (PTable index : parentTable.getIndexes()) {
                    indexes.add(TableName.valueOf(index.getPhysicalName().getBytes()));
                }
            } else {
                // Mapped View
                cParentPhysicalName = SchemaUtil.getTableNameAsBytes(schemaName, tableName);
            }
            parentSchemaName = parentPhysicalSchemaTableNames[1];
            parentTableName = parentPhysicalSchemaTableNames[2];
        } else if (tableType == PTableType.INDEX) {
            parentSchemaName = schemaName;
            /* 
                 * For an index we lock the parent table's row which could be a physical table or a view.
                 * If the parent table is a physical table, then the tenantIdBytes is empty because
                 * we allow creating an index with a tenant connection only if the parent table is a view.
                 */
            parentTableName = MetaDataUtil.getParentTableName(tableMetadata);
            parentTableKey = SchemaUtil.getTableKey(tenantIdBytes, parentSchemaName, parentTableName);
            long clientTimeStamp = MetaDataUtil.getClientTimeStamp(tableMetadata);
            PTable parentTable = loadTable(env, parentTableKey, new ImmutableBytesPtr(parentTableKey), clientTimeStamp, clientTimeStamp, clientVersion);
            if (IndexType.LOCAL == indexType) {
                cPhysicalName = parentTable.getPhysicalName().getBytes();
                cParentPhysicalName = parentTable.getPhysicalName().getBytes();
            } else if (parentTable.getType() == PTableType.VIEW) {
                cPhysicalName = MetaDataUtil.getViewIndexPhysicalName(parentTable.getPhysicalName().getBytes());
                cParentPhysicalName = parentTable.getPhysicalName().getBytes();
            } else {
                cParentPhysicalName = SchemaUtil.getPhysicalHBaseTableName(parentSchemaName, parentTableName, isNamespaceMapped).getBytes();
            }
        }
        getCoprocessorHost().preCreateTable(Bytes.toString(tenantIdBytes), SchemaUtil.getTableName(schemaName, tableName), (tableType == PTableType.VIEW) ? null : TableName.valueOf(cPhysicalName), cParentPhysicalName == null ? null : TableName.valueOf(cParentPhysicalName), tableType, /* TODO: During inital create we may not need the family map */
        Collections.<byte[]>emptySet(), indexes);
        Region region = env.getRegion();
        List<RowLock> locks = Lists.newArrayList();
        // Place a lock using key for the table to be created
        byte[] tableKey = SchemaUtil.getTableKey(tenantIdBytes, schemaName, tableName);
        try {
            acquireLock(region, tableKey, locks);
            // If the table key resides outside the region, return without doing anything
            MetaDataMutationResult result = checkTableKeyInRegion(tableKey, region);
            if (result != null) {
                done.run(MetaDataMutationResult.toProto(result));
                return;
            }
            long clientTimeStamp = MetaDataUtil.getClientTimeStamp(tableMetadata);
            ImmutableBytesPtr parentCacheKey = null;
            PTable parentTable = null;
            if (parentTableName != null) {
                // Check if the parent table resides in the same region. If not, don't worry about locking the parent table row
                // or loading the parent table. For a view, the parent table that needs to be locked is the base physical table.
                // For an index on view, the view header row needs to be locked.
                result = checkTableKeyInRegion(parentTableKey, region);
                if (result == null) {
                    acquireLock(region, parentTableKey, locks);
                    parentCacheKey = new ImmutableBytesPtr(parentTableKey);
                    parentTable = loadTable(env, parentTableKey, parentCacheKey, clientTimeStamp, clientTimeStamp, clientVersion);
                    if (parentTable == null || isTableDeleted(parentTable)) {
                        builder.setReturnCode(MetaDataProtos.MutationCode.PARENT_TABLE_NOT_FOUND);
                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                        done.run(builder.build());
                        return;
                    }
                    // make sure we haven't gone over our threshold for indexes on this table.
                    if (execeededIndexQuota(tableType, parentTable)) {
                        builder.setReturnCode(MetaDataProtos.MutationCode.TOO_MANY_INDEXES);
                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                        done.run(builder.build());
                        return;
                    }
                    long parentTableSeqNumber;
                    if (tableType == PTableType.VIEW && viewPhysicalTableRow != null && request.hasClientVersion()) {
                        // Starting 4.5, the client passes the sequence number of the physical table in the table metadata.
                        parentTableSeqNumber = MetaDataUtil.getSequenceNumber(viewPhysicalTableRow);
                    } else if (tableType == PTableType.VIEW && !request.hasClientVersion()) {
                        // Before 4.5, due to a bug, the parent table key wasn't available.
                        // So don't do anything and prevent the exception from being thrown.
                        parentTableSeqNumber = parentTable.getSequenceNumber();
                    } else {
                        parentTableSeqNumber = MetaDataUtil.getParentSequenceNumber(tableMetadata);
                    }
                    // If parent table isn't at the expected sequence number, then return
                    if (parentTable.getSequenceNumber() != parentTableSeqNumber) {
                        builder.setReturnCode(MetaDataProtos.MutationCode.CONCURRENT_TABLE_MUTATION);
                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                        builder.setTable(PTableImpl.toProto(parentTable));
                        done.run(builder.build());
                        return;
                    }
                }
            }
            // Load child table next
            ImmutableBytesPtr cacheKey = new ImmutableBytesPtr(tableKey);
            // Get as of latest timestamp so we can detect if we have a newer table that already
            // exists without making an additional query
            PTable table = loadTable(env, tableKey, cacheKey, clientTimeStamp, HConstants.LATEST_TIMESTAMP, clientVersion);
            if (table != null) {
                if (table.getTimeStamp() < clientTimeStamp) {
                    // continue
                    if (!isTableDeleted(table)) {
                        builder.setReturnCode(MetaDataProtos.MutationCode.TABLE_ALREADY_EXISTS);
                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                        builder.setTable(PTableImpl.toProto(table));
                        done.run(builder.build());
                        return;
                    }
                } else {
                    builder.setReturnCode(MetaDataProtos.MutationCode.NEWER_TABLE_FOUND);
                    builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                    builder.setTable(PTableImpl.toProto(table));
                    done.run(builder.build());
                    return;
                }
            }
            // sends over depending on its base physical table.
            if (tableType != PTableType.VIEW) {
                UpgradeUtil.addRowKeyOrderOptimizableCell(tableMetadata, tableKey, clientTimeStamp);
            }
            // tableMetadata and set the view statement and partition column correctly
            if (parentTable != null && parentTable.getAutoPartitionSeqName() != null) {
                long autoPartitionNum = 1;
                try (PhoenixConnection connection = QueryUtil.getConnectionOnServer(env.getConfiguration()).unwrap(PhoenixConnection.class);
                    Statement stmt = connection.createStatement()) {
                    String seqName = parentTable.getAutoPartitionSeqName();
                    // Not going through the standard route of using statement.execute() as that code path
                    // is blocked if the metadata hasn't been been upgraded to the new minor release.
                    String seqNextValueSql = String.format("SELECT NEXT VALUE FOR %s", seqName);
                    PhoenixStatement ps = stmt.unwrap(PhoenixStatement.class);
                    QueryPlan plan = ps.compileQuery(seqNextValueSql);
                    ResultIterator resultIterator = plan.iterator();
                    PhoenixResultSet rs = ps.newResultSet(resultIterator, plan.getProjector(), plan.getContext());
                    rs.next();
                    autoPartitionNum = rs.getLong(1);
                } catch (SequenceNotFoundException e) {
                    builder.setReturnCode(MetaDataProtos.MutationCode.AUTO_PARTITION_SEQUENCE_NOT_FOUND);
                    builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                    done.run(builder.build());
                    return;
                }
                PColumn autoPartitionCol = parentTable.getPKColumns().get(MetaDataUtil.getAutoPartitionColIndex(parentTable));
                if (!PLong.INSTANCE.isCoercibleTo(autoPartitionCol.getDataType(), autoPartitionNum)) {
                    builder.setReturnCode(MetaDataProtos.MutationCode.CANNOT_COERCE_AUTO_PARTITION_ID);
                    builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                    done.run(builder.build());
                    return;
                }
                builder.setAutoPartitionNum(autoPartitionNum);
                // set the VIEW STATEMENT column of the header row
                Put tableHeaderPut = MetaDataUtil.getPutOnlyTableHeaderRow(tableMetadata);
                NavigableMap<byte[], List<Cell>> familyCellMap = tableHeaderPut.getFamilyCellMap();
                List<Cell> cells = familyCellMap.get(TABLE_FAMILY_BYTES);
                Cell cell = cells.get(0);
                String autoPartitionWhere = QueryUtil.getViewPartitionClause(MetaDataUtil.getAutoPartitionColumnName(parentTable), autoPartitionNum);
                String hbaseVersion = VersionInfo.getVersion();
                ImmutableBytesPtr ptr = new ImmutableBytesPtr();
                KeyValueBuilder kvBuilder = KeyValueBuilder.get(hbaseVersion);
                MetaDataUtil.getMutationValue(tableHeaderPut, VIEW_STATEMENT_BYTES, kvBuilder, ptr);
                byte[] value = ptr.copyBytesIfNecessary();
                byte[] viewStatement = null;
                // if we have an existing where clause add the auto partition where clause to it
                if (!Bytes.equals(value, QueryConstants.EMPTY_COLUMN_VALUE_BYTES)) {
                    viewStatement = Bytes.add(value, Bytes.toBytes(" AND "), Bytes.toBytes(autoPartitionWhere));
                } else {
                    viewStatement = Bytes.toBytes(QueryUtil.getViewStatement(parentTable.getSchemaName().getString(), parentTable.getTableName().getString(), autoPartitionWhere));
                }
                Cell viewStatementCell = new KeyValue(cell.getRow(), cell.getFamily(), VIEW_STATEMENT_BYTES, cell.getTimestamp(), Type.codeToType(cell.getTypeByte()), viewStatement);
                cells.add(viewStatementCell);
                // set the IS_VIEW_REFERENCED column of the auto partition column row
                Put autoPartitionPut = MetaDataUtil.getPutOnlyAutoPartitionColumn(parentTable, tableMetadata);
                familyCellMap = autoPartitionPut.getFamilyCellMap();
                cells = familyCellMap.get(TABLE_FAMILY_BYTES);
                cell = cells.get(0);
                PDataType dataType = autoPartitionCol.getDataType();
                Object val = dataType.toObject(autoPartitionNum, PLong.INSTANCE);
                byte[] bytes = new byte[dataType.getByteSize() + 1];
                dataType.toBytes(val, bytes, 0);
                Cell viewConstantCell = new KeyValue(cell.getRow(), cell.getFamily(), VIEW_CONSTANT_BYTES, cell.getTimestamp(), Type.codeToType(cell.getTypeByte()), bytes);
                cells.add(viewConstantCell);
            }
            Short indexId = null;
            if (request.hasAllocateIndexId() && request.getAllocateIndexId()) {
                String tenantIdStr = tenantIdBytes.length == 0 ? null : Bytes.toString(tenantIdBytes);
                try (PhoenixConnection connection = QueryUtil.getConnectionOnServer(env.getConfiguration()).unwrap(PhoenixConnection.class)) {
                    PName physicalName = parentTable.getPhysicalName();
                    int nSequenceSaltBuckets = connection.getQueryServices().getSequenceSaltBuckets();
                    SequenceKey key = MetaDataUtil.getViewIndexSequenceKey(tenantIdStr, physicalName, nSequenceSaltBuckets, parentTable.isNamespaceMapped());
                    // TODO Review Earlier sequence was created at (SCN-1/LATEST_TIMESTAMP) and incremented at the client max(SCN,dataTable.getTimestamp), but it seems we should
                    // use always LATEST_TIMESTAMP to avoid seeing wrong sequence values by different connection having SCN
                    // or not.
                    long sequenceTimestamp = HConstants.LATEST_TIMESTAMP;
                    try {
                        connection.getQueryServices().createSequence(key.getTenantId(), key.getSchemaName(), key.getSequenceName(), Short.MIN_VALUE, 1, 1, Long.MIN_VALUE, Long.MAX_VALUE, false, sequenceTimestamp);
                    } catch (SequenceAlreadyExistsException e) {
                    }
                    long[] seqValues = new long[1];
                    SQLException[] sqlExceptions = new SQLException[1];
                    connection.getQueryServices().incrementSequences(Collections.singletonList(new SequenceAllocation(key, 1)), HConstants.LATEST_TIMESTAMP, seqValues, sqlExceptions);
                    if (sqlExceptions[0] != null) {
                        throw sqlExceptions[0];
                    }
                    long seqValue = seqValues[0];
                    if (seqValue > Short.MAX_VALUE) {
                        builder.setReturnCode(MetaDataProtos.MutationCode.TOO_MANY_INDEXES);
                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
                        done.run(builder.build());
                        return;
                    }
                    Put tableHeaderPut = MetaDataUtil.getPutOnlyTableHeaderRow(tableMetadata);
                    NavigableMap<byte[], List<Cell>> familyCellMap = tableHeaderPut.getFamilyCellMap();
                    List<Cell> cells = familyCellMap.get(TABLE_FAMILY_BYTES);
                    Cell cell = cells.get(0);
                    PDataType dataType = MetaDataUtil.getViewIndexIdDataType();
                    Object val = dataType.toObject(seqValue, PLong.INSTANCE);
                    byte[] bytes = new byte[dataType.getByteSize() + 1];
                    dataType.toBytes(val, bytes, 0);
                    Cell indexIdCell = new KeyValue(cell.getRow(), cell.getFamily(), VIEW_INDEX_ID_BYTES, cell.getTimestamp(), Type.codeToType(cell.getTypeByte()), bytes);
                    cells.add(indexIdCell);
                    indexId = (short) seqValue;
                }
            }
            // TODO: Switch this to HRegion#batchMutate when we want to support indexes on the
            // system table. Basically, we get all the locks that we don't already hold for all the
            // tableMetadata rows. This ensures we don't have deadlock situations (ensuring
            // primary and then index table locks are held, in that order). For now, we just don't support
            // indexing on the system table. This is an issue because of the way we manage batch mutation
            // in the Indexer.
            mutateRowsWithLocks(region, tableMetadata, Collections.<byte[]>emptySet(), HConstants.NO_NONCE, HConstants.NO_NONCE);
            // Invalidate the cache - the next getTable call will add it
            // TODO: consider loading the table that was just created here, patching up the parent table, and updating the cache
            Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env).getMetaDataCache();
            if (parentCacheKey != null) {
                metaDataCache.invalidate(parentCacheKey);
            }
            metaDataCache.invalidate(cacheKey);
            // Get timeStamp from mutations - the above method sets it if it's unset
            long currentTimeStamp = MetaDataUtil.getClientTimeStamp(tableMetadata);
            builder.setReturnCode(MetaDataProtos.MutationCode.TABLE_NOT_FOUND);
            if (indexId != null) {
                builder.setViewIndexId(indexId);
            }
            builder.setMutationTime(currentTimeStamp);
            done.run(builder.build());
            return;
        } finally {
            releaseRowLocks(region, locks);
        }
    } catch (Throwable t) {
        logger.error("createTable failed", t);
        ProtobufUtil.setControllerException(controller, ServerUtil.createIOException(SchemaUtil.getTableName(schemaName, tableName), t));
    }
}
Also used : ByteString(com.google.protobuf.ByteString) PhoenixStatement(org.apache.phoenix.jdbc.PhoenixStatement) PTable(org.apache.phoenix.schema.PTable) PDataType(org.apache.phoenix.schema.types.PDataType) FilterList(org.apache.hadoop.hbase.filter.FilterList) ArrayList(java.util.ArrayList) List(java.util.List) Cell(org.apache.hadoop.hbase.Cell) HashSet(java.util.HashSet) ImmutableBytesWritable(org.apache.hadoop.hbase.io.ImmutableBytesWritable) ImmutableBytesPtr(org.apache.phoenix.hbase.index.util.ImmutableBytesPtr) ResultIterator(org.apache.phoenix.iterate.ResultIterator) SequenceAllocation(org.apache.phoenix.schema.SequenceAllocation) TableName(org.apache.hadoop.hbase.TableName) Region(org.apache.hadoop.hbase.regionserver.Region) Mutation(org.apache.hadoop.hbase.client.Mutation) PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) KeyValue(org.apache.hadoop.hbase.KeyValue) SQLException(java.sql.SQLException) SequenceAlreadyExistsException(org.apache.phoenix.schema.SequenceAlreadyExistsException) QueryPlan(org.apache.phoenix.compile.QueryPlan) PColumn(org.apache.phoenix.schema.PColumn) SequenceKey(org.apache.phoenix.schema.SequenceKey) PMetaDataEntity(org.apache.phoenix.schema.PMetaDataEntity) SequenceNotFoundException(org.apache.phoenix.schema.SequenceNotFoundException) IndexType(org.apache.phoenix.schema.PTable.IndexType) RowLock(org.apache.hadoop.hbase.regionserver.Region.RowLock) MetaDataResponse(org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataResponse) PhoenixStatement(org.apache.phoenix.jdbc.PhoenixStatement) Statement(java.sql.Statement) PTableType(org.apache.phoenix.schema.PTableType) KeyValueBuilder(org.apache.phoenix.hbase.index.util.KeyValueBuilder) GenericKeyValueBuilder(org.apache.phoenix.hbase.index.util.GenericKeyValueBuilder) PTinyint(org.apache.phoenix.schema.types.PTinyint) PSmallint(org.apache.phoenix.schema.types.PSmallint) Put(org.apache.hadoop.hbase.client.Put) PhoenixResultSet(org.apache.phoenix.jdbc.PhoenixResultSet) PName(org.apache.phoenix.schema.PName)

Example 5 with SequenceAllocation

use of org.apache.phoenix.schema.SequenceAllocation in project phoenix by apache.

the class SequenceManager method validateSequences.

public void validateSequences(Sequence.ValueOp action) throws SQLException {
    if (sequenceMap.isEmpty()) {
        return;
    }
    int maxSize = sequenceMap.size();
    long[] dstSequenceValues = new long[maxSize];
    sequencePosition = new int[maxSize];
    nextSequences = Lists.newArrayListWithExpectedSize(maxSize);
    currentSequences = Lists.newArrayListWithExpectedSize(maxSize);
    for (Map.Entry<SequenceKey, SequenceValueExpression> entry : sequenceMap.entrySet()) {
        if (isNextSequence.get(entry.getValue().getIndex())) {
            nextSequences.add(new SequenceAllocation(entry.getKey(), entry.getValue().getNumToAllocate()));
        } else {
            currentSequences.add(entry.getKey());
        }
    }
    long[] srcSequenceValues = new long[nextSequences.size()];
    SQLException[] sqlExceptions = new SQLException[nextSequences.size()];
    // Sort the next sequences to prevent deadlocks
    Collections.sort(nextSequences);
    // Create reverse indexes
    for (int i = 0; i < nextSequences.size(); i++) {
        sequencePosition[i] = sequenceMap.get(nextSequences.get(i).getSequenceKey()).getIndex();
    }
    int offset = nextSequences.size();
    for (int i = 0; i < currentSequences.size(); i++) {
        sequencePosition[i + offset] = sequenceMap.get(currentSequences.get(i)).getIndex();
    }
    ConnectionQueryServices services = this.statement.getConnection().getQueryServices();
    Long scn = statement.getConnection().getSCN();
    long timestamp = scn == null ? HConstants.LATEST_TIMESTAMP : scn;
    services.validateSequences(nextSequences, timestamp, srcSequenceValues, sqlExceptions, action);
    setSequenceValues(srcSequenceValues, dstSequenceValues, sqlExceptions);
}
Also used : SequenceKey(org.apache.phoenix.schema.SequenceKey) SQLException(java.sql.SQLException) PLong(org.apache.phoenix.schema.types.PLong) SequenceAllocation(org.apache.phoenix.schema.SequenceAllocation) Map(java.util.Map) ConnectionQueryServices(org.apache.phoenix.query.ConnectionQueryServices)

Aggregations

SequenceAllocation (org.apache.phoenix.schema.SequenceAllocation)5 SQLException (java.sql.SQLException)4 SequenceKey (org.apache.phoenix.schema.SequenceKey)4 SequenceNotFoundException (org.apache.phoenix.schema.SequenceNotFoundException)3 SQLExceptionInfo (org.apache.phoenix.exception.SQLExceptionInfo)2 PTinyint (org.apache.phoenix.schema.types.PTinyint)2 ByteString (com.google.protobuf.ByteString)1 IOException (java.io.IOException)1 Statement (java.sql.Statement)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Cell (org.apache.hadoop.hbase.Cell)1 KeyValue (org.apache.hadoop.hbase.KeyValue)1 TableName (org.apache.hadoop.hbase.TableName)1 HTableInterface (org.apache.hadoop.hbase.client.HTableInterface)1 Increment (org.apache.hadoop.hbase.client.Increment)1 Mutation (org.apache.hadoop.hbase.client.Mutation)1 Put (org.apache.hadoop.hbase.client.Put)1