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

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

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

    https://github.com/apache/phoenix/pull/355#discussion_r224306505
  
    --- Diff: 
phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
 ---
    @@ -4588,4 +4424,195 @@ private TableName getParentPhysicalTableName(PTable 
table) {
                                                                     
table.getTableName(), table.isNamespaceMapped())
                                                             .getBytes());
         }
    +
    +    private class TableBuilder {
    +        private Region region;
    +        private byte[] tableKey;
    +        private Integer clientVersion;
    +
    +        public TableBuilder setRegion(Region region) {
    +            this.region = region;
    +            return this;
    +        }
    +
    +        public TableBuilder setTableKey(byte[] tableKey) {
    +            this.tableKey = tableKey;
    +            return this;
    +        }
    +
    +        public TableBuilder setClientVersion(Integer clientVersion) {
    +            this.clientVersion = clientVersion;
    +            return this;
    +        }
    +
    +        public PTable run() throws Exception {
    +            Preconditions.checkNotNull(region);
    +            Preconditions.checkNotNull(tableKey);
    +            Preconditions.checkNotNull(clientVersion);
    +            ImmutableBytesPtr cacheKey = new ImmutableBytesPtr(tableKey);
    +            return buildTable(tableKey, cacheKey, region, 
HConstants.LATEST_TIMESTAMP, clientVersion,
    +                    false, false, null);
    +        }
    +    }
    +
    +
    +    /**
    +     * Indexes table and View will not be modify when the parent tables 
are modified, so modify has a simple logic in server side.
    +     * @param controller
    +     * @param request
    +     * @param done
    +     */
    +    @Override
    +    public void modifyColumn(RpcController controller, final 
MetaDataProtos.ModifyColumnRequest request,
    +            RpcCallback<MetaDataResponse> done) {
    +        try {
    +            final List<Mutation> metaData = 
ProtobufUtil.getMutations(request);
    +            final TableBuilder tableBuilder = new TableBuilder();
    +            MetaDataMutationResult result = 
mutateColumn(MutatateColumnType.MODIFY_COLUMN, metaData, new ColumnMutator() {
    +
    +                @Override
    +                public MetaDataMutationResult updateMutation(PTable table, 
byte[][] rowKeyMetaData,
    +                        List<Mutation> tableMetadata, Region region,
    +                        List<ImmutableBytesPtr> invalidateList, 
List<RowLock> locks,
    +                        long clientTimeStamp) throws IOException, 
SQLException {
    +
    +                    Preconditions.checkArgument(rowKeyMetaData.length == 
5);
    +                    byte[] tenantId = 
rowKeyMetaData[PhoenixDatabaseMetaData.TENANT_ID_INDEX];
    +                    byte[] schemaName = 
rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX];
    +                    byte[] tableName = 
rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX];
    +                    byte[] key = SchemaUtil.getTableKey(tenantId, 
schemaName, tableName);
    +
    +                    PColumn column = null;
    +                    Cell dataTypeCell = null;
    +                    Cell columnSizeCell = null;
    +                    Cell decimalDigitCell = null;
    +                    List<byte[]> mutatedTableNames = new ArrayList<>();
    +                    byte[] familyName = 
QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;
    +
    +                    try {
    +                        for (Mutation m : metaData) {
    +                            byte[][] rkmd = new byte[5][];
    +                            int pkCount = getVarChars(m.getRow(), rkmd);
    +
    +                            // Checking this put is for modifying a column
    +                            if (pkCount < COLUMN_NAME_INDEX || !(m 
instanceof Put)
    +                                    || 
rkmd[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX] == null) {
    +                                continue;
    +                            }
    +
    +                            List<Cell> cells;
    +                            if 
(rkmd[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX] != null) {
    +                                PColumnFamily family = 
table.getColumnFamily(rkmd[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]);
    +                                column = 
family.getPColumnForColumnNameBytes(rkmd[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]);
    +                                cells = 
m.getFamilyCellMap().get(column.getFamilyName().getBytes());
    +                            } else {
    +                                column = table.getPKColumn(new 
String(rkmd[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]));
    +                                cells = 
m.getFamilyCellMap().get(familyName);
    +                            }
    +
    +                            for (Cell cell : cells) {
    +                                if 
(Bytes.compareTo(CellUtil.cloneQualifier(cell), 
PhoenixDatabaseMetaData.DATA_TYPE_BYTES) == 0) {
    +                                    dataTypeCell = cell;
    +                                } else if 
(Bytes.compareTo(CellUtil.cloneQualifier(cell), 
PhoenixDatabaseMetaData.COLUMN_SIZE_BYTES) == 0) {
    +                                    columnSizeCell = cell;
    +                                } else if 
(Bytes.compareTo(CellUtil.cloneQualifier(cell), 
PhoenixDatabaseMetaData.DECIMAL_DIGITS_BYTES) == 0) {
    +                                    decimalDigitCell = cell;
    +                                }
    +                            }
    +                        }
    +
    +                        // After PHOENIX-3534, we don't store parent table 
column metadata along with the child metadata,
    +                        // so we don't need to propagate changes to the 
child views.
    +
    +                        if (!table.getIndexes().isEmpty()) {
    +                            PhoenixConnection connection = null;
    +                            try {
    +                                connection = 
QueryUtil.getConnectionOnServer(env.getConfiguration()).unwrap(PhoenixConnection.class);
    +                            } catch (ClassNotFoundException e) {
    +                            }
    +
    +                            for (PTable index : table.getIndexes()) {
    +                                byte[] tenantIdBytes = index.getTenantId() 
== null ?
    +                                                ByteUtil.EMPTY_BYTE_ARRAY :
    +                                                
index.getTenantId().getBytes();
    +                                byte[] schemaNameBytes = 
index.getSchemaName().getBytes();
    +                                byte[] indexName = 
index.getTableName().getBytes();
    +                                byte[] indexKey = 
SchemaUtil.getTableKey(tenantIdBytes, schemaNameBytes, indexName);
    +
    +                                IndexMaintainer indexMaintainer = 
index.getIndexMaintainer(table, connection);
    +                                boolean isColumnIndexed = 
indexMaintainer.getIndexedColumnInfo().contains(
    +                                                new 
Pair<>(column.getFamilyName().getString(), column.getName().getString()));
    +                                ColumnReference coveredColumn = 
indexMaintainer.getCoveredColumnsOfIndexTable(
    +                                                new 
ColumnReference(column.getFamilyName().getBytes(), 
column.getColumnQualifierBytes()));
    +
    +                                // Since the columns of fixed length which 
in present in primary key of index table will be converted
    +                                // to variable length when index tables 
are created, So we will not process indexed columns.
    +                                if (isColumnIndexed) {
    --- End diff --
    
    Ok


> Support multi region SYSTEM.CATALOG table
> -----------------------------------------
>
>                 Key: PHOENIX-3534
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-3534
>             Project: Phoenix
>          Issue Type: Bug
>            Reporter: James Taylor
>            Assignee: Thomas D'Silva
>            Priority: Major
>             Fix For: 4.15.0, 5.1.0
>
>         Attachments: PHOENIX-3534-v2.patch, PHOENIX-3534-v3.patch, 
> PHOENIX-3534.patch
>
>
> Currently Phoenix requires that the SYSTEM.CATALOG table is single region 
> based on the server-side row locks being held for operations that impact a 
> table and all of it's views. For example, adding/removing a column from a 
> base table pushes this change to all views.
> As an alternative to making the SYSTEM.CATALOG transactional (PHOENIX-2431), 
> when a new table is created we can do a lazy cleanup  of any rows that may be 
> left over from a failed DDL call (kudos to [~lhofhansl] for coming up with 
> this idea). To implement this efficiently, we'd need to also do PHOENIX-2051 
> so that we can efficiently find derived views.
> The implementation would rely on an optimistic concurrency model based on 
> checking our sequence numbers for each table/view before/after updating. Each 
> table/view row would be individually locked for their change (metadata for a 
> view or table cannot span regions due to our split policy), with the sequence 
> number being incremented under lock and then returned to the client.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to