You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@phoenix.apache.org by "ASF GitHub Bot (JIRA)" <ji...@apache.org> on 2016/04/01 08:24:25 UTC

[jira] [Commented] (PHOENIX-1311) HBase namespaces surfaced in phoenix

    [ https://issues.apache.org/jira/browse/PHOENIX-1311?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15221234#comment-15221234 ] 

ASF GitHub Bot commented on PHOENIX-1311:
-----------------------------------------

Github user JamesRTaylor commented on a diff in the pull request:

    https://github.com/apache/phoenix/pull/153#discussion_r58166396
  
    --- Diff: phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java ---
    @@ -3201,4 +3367,155 @@ private MetaDataMutationResult doDropFunction(long clientTimeStamp, List<byte[]>
             return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND,
                     EnvironmentEdgeManager.currentTimeMillis(), null);
         }
    +
    +    @Override
    +    public void createSchema(RpcController controller, CreateSchemaRequest request,
    +            RpcCallback<MetaDataResponse> done) {
    +        MetaDataResponse.Builder builder = MetaDataResponse.newBuilder();
    +        String schemaName = null;
    +        try {
    +            List<Mutation> schemaMutations = ProtobufUtil.getMutations(request);
    +            schemaName = request.getSchemaName();
    +            Mutation m = MetaDataUtil.getPutOnlyTableHeaderRow(schemaMutations);
    +
    +            byte[] lockKey = m.getRow();
    +            Region region = env.getRegion();
    +            MetaDataMutationResult result = checkSchemaKeyInRegion(lockKey, region);
    +            if (result != null) {
    +                done.run(MetaDataMutationResult.toProto(result));
    +                return;
    +            }
    +            List<RowLock> locks = Lists.newArrayList();
    +            long clientTimeStamp = MetaDataUtil.getClientTimeStamp(schemaMutations);
    +            try {
    +                acquireLock(region, lockKey, locks);
    +                // Get as of latest timestamp so we can detect if we have a
    +                // newer function that already
    +                // exists without making an additional query
    +                ImmutableBytesPtr cacheKey = new ImmutableBytesPtr(lockKey);
    +                PSchema schema = loadSchema(env, lockKey, cacheKey, clientTimeStamp, clientTimeStamp);
    +                if (schema != null) {
    +                    if (schema.getTimeStamp() < clientTimeStamp) {
    +                        builder.setReturnCode(MetaDataProtos.MutationCode.SCHEMA_ALREADY_EXISTS);
    +                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
    +                        builder.setSchema(PSchema.toProto(schema));
    +                        done.run(builder.build());
    +                        return;
    +                    } else {
    +                        builder.setReturnCode(MetaDataProtos.MutationCode.NEWER_SCHEMA_FOUND);
    +                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
    +                        builder.setSchema(PSchema.toProto(schema));
    +                        done.run(builder.build());
    +                        return;
    +                    }
    +                }
    +                region.mutateRowsWithLocks(schemaMutations, 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 (cacheKey != null) {
    +                    metaDataCache.invalidate(cacheKey);
    +                }
    +
    +                // Get timeStamp from mutations - the above method sets it if
    +                // it's unset
    +                long currentTimeStamp = MetaDataUtil.getClientTimeStamp(schemaMutations);
    +                builder.setReturnCode(MetaDataProtos.MutationCode.SCHEMA_NOT_FOUND);
    +                builder.setMutationTime(currentTimeStamp);
    +                done.run(builder.build());
    +                return;
    +            } finally {
    +                region.releaseRowLocks(locks);
    +            }
    +        } catch (Throwable t) {
    +            logger.error("createFunction failed", t);
    +            ProtobufUtil.setControllerException(controller, ServerUtil.createIOException(schemaName, t));
    +        }
    +    }
    +
    +    @Override
    +    public void dropSchema(RpcController controller, DropSchemaRequest request, RpcCallback<MetaDataResponse> done) {
    +        String schemaName = null;
    +        try {
    +            List<Mutation> schemaMetaData = ProtobufUtil.getMutations(request);
    +            schemaName = request.getSchemaName();
    +            byte[] lockKey = SchemaUtil.getSchemaKey(schemaName);
    +            Region region = env.getRegion();
    +            MetaDataMutationResult result = checkSchemaKeyInRegion(lockKey, region);
    +            if (result != null) {
    +                done.run(MetaDataMutationResult.toProto(result));
    +                return;
    +            }
    +            List<RowLock> locks = Lists.newArrayList();
    +            long clientTimeStamp = MetaDataUtil.getClientTimeStamp(schemaMetaData);
    +            try {
    +                acquireLock(region, lockKey, locks);
    +                List<ImmutableBytesPtr> invalidateList = new ArrayList<ImmutableBytesPtr>(1);
    +                result = doDropSchema(clientTimeStamp, schemaName, lockKey, schemaMetaData, invalidateList);
    +                if (result.getMutationCode() != MutationCode.SCHEMA_ALREADY_EXISTS) {
    +                    done.run(MetaDataMutationResult.toProto(result));
    +                    return;
    +                }
    +                region.mutateRowsWithLocks(schemaMetaData, Collections.<byte[]> emptySet(), HConstants.NO_NONCE,
    +                        HConstants.NO_NONCE);
    +                Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env)
    +                        .getMetaDataCache();
    +                long currentTime = MetaDataUtil.getClientTimeStamp(schemaMetaData);
    +                for (ImmutableBytesPtr ptr : invalidateList) {
    +                    metaDataCache.invalidate(ptr);
    +                    metaDataCache.put(ptr, newDeletedSchemaMarker(currentTime));
    +                }
    +                done.run(MetaDataMutationResult.toProto(result));
    +                return;
    +            } finally {
    +                region.releaseRowLocks(locks);
    +            }
    +        } catch (Throwable t) {
    +            logger.error("drop schema failed:", t);
    +            ProtobufUtil.setControllerException(controller, ServerUtil.createIOException(schemaName, t));
    +        }
    +    }
    +
    +    private MetaDataMutationResult doDropSchema(long clientTimeStamp, String schemaName, byte[] key,
    +            List<Mutation> schemaMutations, List<ImmutableBytesPtr> invalidateList) throws IOException, SQLException {
    +        PSchema schema = loadSchema(env, key, new ImmutableBytesPtr(key), clientTimeStamp, clientTimeStamp);
    +        boolean areTablesExists = false;
    +        if (schema == null) { return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND,
    +                EnvironmentEdgeManager.currentTimeMillis(), null); }
    +        if (schema.getTimeStamp() < clientTimeStamp) {
    +            Region region = env.getRegion();
    +            Scan scan = MetaDataUtil.newTableRowsScan(SchemaUtil.getKeyForSchema(null, schemaName), MIN_TABLE_TIMESTAMP,
    +                    clientTimeStamp);
    +            List<Cell> results = Lists.newArrayList();
    +            try (RegionScanner scanner = region.getScanner(scan);) {
    +                scanner.next(results);
    +                if (results.isEmpty()) { // Should not be possible
    +                    return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND,
    +                            EnvironmentEdgeManager.currentTimeMillis(), null);
    +                }
    +                do {
    +                    Cell kv = results.get(0);
    +                    if (Bytes.compareTo(kv.getRowArray(), kv.getRowOffset(), kv.getRowLength(), key, 0,
    +                            key.length) != 0) {
    +                        areTablesExists = true;
    +                        break;
    +                    }
    +                    results.clear();
    +                    scanner.next(results);
    +                } while (!results.isEmpty());
    +            }
    +            if (areTablesExists) { return new MetaDataMutationResult(MutationCode.UNALLOWED_SCHEMA_MUTATION, schema,
    --- End diff --
    
    These changes can be done in a separate pull request, though IMO.


> HBase namespaces surfaced in phoenix
> ------------------------------------
>
>                 Key: PHOENIX-1311
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-1311
>             Project: Phoenix
>          Issue Type: New Feature
>            Reporter: nicolas maillard
>            Assignee: Ankit Singhal
>            Priority: Minor
>             Fix For: 4.8.0
>
>         Attachments: PHOENIX-1311.docx, PHOENIX-1311_v1.patch, PHOENIX-1311_v2.patch, PHOENIX-1311_wip.patch, PHOENIX-1311_wip_2.patch
>
>
> Hbase (HBASE-8015) has the concept of namespaces in the form of myNamespace:MyTable it would be great if Phoenix leveraged this feature to give a database like feature on top of the table.
> Maybe to stay close to Hbase it could also be a create DB:Table...
> or DB.Table which is a more standard annotation?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)