abhishek-chouhan commented on a change in pull request #699: PHOENIX-5496 
Ensure that we handle all server-side mutation codes on the client
URL: https://github.com/apache/phoenix/pull/699#discussion_r377983558
 
 

 ##########
 File path: 
phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
 ##########
 @@ -2957,149 +2958,180 @@ public boolean isViewReferenced() {
                 splits = SchemaUtil.processSplits(splits, pkColumns, 
saltBucketNum, connection.getQueryServices().getProps().getBoolean(
                         QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB, 
QueryServicesOptions.DEFAULT_FORCE_ROW_KEY_ORDER));
             }
-            MetaDataMutationResult result = 
connection.getQueryServices().createTable(
-                    tableMetaData,
-                    viewType == ViewType.MAPPED || allocateIndexId ? 
physicalNames.get(0).getBytes() : null,
-                    tableType, tableProps, familyPropList, splits, 
isNamespaceMapped, allocateIndexId,
-                    UpgradeUtil.isNoUpgradeSet(connection.getClientInfo()), 
parent);
+
+                       // Modularized this code for unit testing
+            MetaDataMutationResult result = 
getCreateTableMutationResult(tableMetaData, viewType,
+                    allocateIndexId, physicalNames, tableType, tableProps, 
familyPropList, splits,
+                    isNamespaceMapped, parent);
             MutationCode code = result.getMutationCode();
-            switch(code) {
+            if (code != MutationCode.TABLE_NOT_FOUND) {
+                boolean mutationResult =  
handleCreateTableMutationCode(result, code, statement,
+                        schemaName, tableName, parent);
+                if(mutationResult) {
+                    return null;
+                }
+            }
+            // If the parent table of the view has the auto partition sequence 
name attribute,
+            // set the view statement and relevant partition column attributes 
correctly
+            if (parent!=null && parent.getAutoPartitionSeqName()!=null) {
+                final PColumn autoPartitionCol = 
parent.getPKColumns().get(MetaDataUtil.getAutoPartitionColIndex(parent));
+                final Long autoPartitionNum = 
Long.valueOf(result.getAutoPartitionNum());
+                columns.put(autoPartitionCol, new 
DelegateColumn(autoPartitionCol) {
+                    @Override
+                    public byte[] getViewConstant() {
+                        PDataType dataType = autoPartitionCol.getDataType();
+                        Object val = dataType.toObject(autoPartitionNum, 
PLong.INSTANCE);
+                        byte[] bytes = new byte [dataType.getByteSize() + 1];
+                        dataType.toBytes(val, bytes, 0);
+                        return bytes;
+                    }
+                    @Override
+                    public boolean isViewReferenced() {
+                        return true;
+                    }
+                });
+                String viewPartitionClause = 
QueryUtil.getViewPartitionClause(MetaDataUtil.getAutoPartitionColumnName(parent),
 autoPartitionNum);
+                if (viewStatement!=null) {
+                    viewStatement = viewStatement + " AND " + 
viewPartitionClause;
+                }
+                else {
+                    viewStatement = 
QueryUtil.getViewStatement(parent.getSchemaName().getString(), 
parent.getTableName().getString(), viewPartitionClause);
+                }
+            }
+            PName newSchemaName = PNameFactory.newName(schemaName);
+            /*
+             * It doesn't hurt for the PTable of views to have the cqCounter. 
However, views always rely on the
+             * parent table's counter to dole out encoded column qualifiers. 
So setting the counter as NULL_COUNTER
+             * for extra safety.
+             */
+            EncodedCQCounter cqCounterToBe = tableType == PTableType.VIEW ? 
NULL_COUNTER : cqCounter;
+            PTable table = new PTableImpl.Builder()
+                    .setType(tableType)
+                    .setState(indexState)
+                    .setTimeStamp(timestamp != null ? timestamp : 
result.getMutationTime())
+                    .setIndexDisableTimestamp(0L)
+                    .setSequenceNumber(PTable.INITIAL_SEQ_NUM)
+                    .setImmutableRows(isImmutableRows)
+                    .setViewStatement(viewStatement)
+                    .setDisableWAL(Boolean.TRUE.equals(disableWAL))
+                    .setMultiTenant(multiTenant)
+                    .setStoreNulls(storeNulls)
+                    .setViewType(viewType)
+                    .setViewIndexIdType(viewIndexIdType)
+                    .setViewIndexId(result.getViewIndexId())
+                    .setIndexType(indexType)
+                    .setTransactionProvider(transactionProvider)
+                    .setUpdateCacheFrequency(updateCacheFrequency)
+                    .setNamespaceMapped(isNamespaceMapped)
+                    .setAutoPartitionSeqName(autoPartitionSeq)
+                    .setAppendOnlySchema(isAppendOnlySchema)
+                    .setImmutableStorageScheme(immutableStorageScheme == null ?
+                            ImmutableStorageScheme.ONE_CELL_PER_COLUMN : 
immutableStorageScheme)
+                    .setQualifierEncodingScheme(encodingScheme == null ?
+                            QualifierEncodingScheme.NON_ENCODED_QUALIFIERS : 
encodingScheme)
+                    .setBaseColumnCount(baseTableColumnCount)
+                    .setEncodedCQCounter(cqCounterToBe)
+                    
.setUseStatsForParallelization(useStatsForParallelizationProp)
+                    .setExcludedColumns(ImmutableList.of())
+                    .setTenantId(tenantId)
+                    .setSchemaName(newSchemaName)
+                    .setTableName(PNameFactory.newName(tableName))
+                    .setPkName(pkName == null ? null : 
PNameFactory.newName(pkName))
+                    .setDefaultFamilyName(defaultFamilyName == null ?
+                            null : PNameFactory.newName(defaultFamilyName))
+                    .setRowKeyOrderOptimizable(rowKeyOrderOptimizable)
+                    .setBucketNum(saltBucketNum)
+                    .setIndexes(Collections.emptyList())
+                    .setParentSchemaName((parent == null) ? null : 
parent.getSchemaName())
+                    .setParentTableName((parent == null) ? null : 
parent.getTableName())
+                    .setPhysicalNames(physicalNames == null ?
+                            ImmutableList.of() : 
ImmutableList.copyOf(physicalNames))
+                    .setColumns(columns.values())
+                    .setViewTTL(viewTTL == null ? VIEW_TTL_NOT_DEFINED : 
viewTTL)
+                    .setViewTTLHighWaterMark(viewTTLHighWaterMark == null ? 
MIN_VIEW_TTL_HWM : viewTTLHighWaterMark)
+                    .setViewModifiedUpdateCacheFrequency(tableType ==  
PTableType.VIEW &&
+                            parent != null &&
+                            parent.getUpdateCacheFrequency() != 
updateCacheFrequency)
+                    .setViewModifiedUseStatsForParallelization(tableType ==  
PTableType.VIEW &&
+                            parent != null &&
+                            parent.useStatsForParallelization()
+                                    != useStatsForParallelizationProp)
+                    .setViewModifiedViewTTL(tableType ==  PTableType.VIEW &&
+                            parent != null && viewTTL != null &&
+                            parent.getViewTTL() != viewTTL)
+                    .build();
+            result = new MetaDataMutationResult(code, 
result.getMutationTime(), table, true);
+            addTableToCache(result);
+            return table;
+        } finally {
+            connection.setAutoCommit(wasAutoCommit);
+            deleteMutexCells(parentPhysicalSchemaName, 
parentPhysicalTableName, acquiredColumnMutexSet);
+        }
+    }
+
+    @VisibleForTesting
+    public boolean handleCreateTableMutationCode(MetaDataMutationResult 
result, MutationCode code,
+                 CreateTableStatement statement, String schemaName, String 
tableName,
+                 PTable parent) throws SQLException {
+        switch(code) {
             case TABLE_ALREADY_EXISTS:
-                if (result.getTable() != null) { // Can happen for 
transactional table that already exists as HBase table
+                if(result.getTable() != null) {
                     addTableToCache(result);
                 }
-                if (!statement.ifNotExists()) {
+                if(!statement.ifNotExists()) {
                     throw new TableAlreadyExistsException(schemaName, 
tableName, result.getTable());
                 }
-                return null;
+                return true;
             case NEWER_TABLE_FOUND:
                 // Add table to ConnectionQueryServices so it's cached, but 
don't add
                 // it to this connection as we can't see it.
                 if (!statement.ifNotExists()) {
-                    throw new NewerTableAlreadyExistsException(schemaName, 
tableName, result.getTable());
+                    throw new NewerTableAlreadyExistsException(schemaName, 
tableName,
+                            result.getTable());
                 }
+                return false;
             case UNALLOWED_TABLE_MUTATION:
-                throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_MUTATE_TABLE)
-                    
.setSchemaName(schemaName).setTableName(tableName).build().buildException();
+                
throwsSQLExceptionUtil("CANNOT_MUTATE_TABLE",schemaName,tableName);
             case CONCURRENT_TABLE_MUTATION:
                 addTableToCache(result);
                 throw new ConcurrentTableMutationException(schemaName, 
tableName);
             case AUTO_PARTITION_SEQUENCE_NOT_FOUND:
                 throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.AUTO_PARTITION_SEQUENCE_UNDEFINED)
-                
.setSchemaName(schemaName).setTableName(tableName).build().buildException();
+                       
.setSchemaName(schemaName).setTableName(tableName).build().buildException();
             case CANNOT_COERCE_AUTO_PARTITION_ID:
-                throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_COERCE_AUTO_PARTITION_ID)
-                
.setSchemaName(schemaName).setTableName(tableName).build().buildException();
+            case UNABLE_TO_CREATE_CHILD_LINK:
+            case PARENT_TABLE_NOT_FOUND:
+            case TABLE_NOT_IN_REGION:
+                throwsSQLExceptionUtil(String.valueOf(code), schemaName, 
tableName);
             case TOO_MANY_INDEXES:
-                throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.TOO_MANY_INDEXES)
-                        
.setSchemaName(SchemaUtil.getSchemaNameFromFullName(parent.getPhysicalName().getString()))
-                        
.setTableName(SchemaUtil.getTableNameFromFullName(parent.getPhysicalName().getString())).build()
-                        .buildException();
             case UNABLE_TO_UPDATE_PARENT_TABLE:
-                throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.UNABLE_TO_UPDATE_PARENT_TABLE)
-                        
.setSchemaName(SchemaUtil.getSchemaNameFromFullName(parent.getPhysicalName().getString()))
-                        
.setTableName(SchemaUtil.getTableNameFromFullName(parent.getPhysicalName().getString())).build()
-                        .buildException();
+                throwsSQLExceptionUtil(String.valueOf(code), 
SchemaUtil.getSchemaNameFromFullName(
+                
parent.getPhysicalName().getString()),SchemaUtil.getTableNameFromFullName(
+                parent.getPhysicalName().getString()));
             default:
-                // If the parent table of the view has the auto partition 
sequence name attribute,
-                // set the view statement and relevant partition column 
attributes correctly
-                if (parent!=null && parent.getAutoPartitionSeqName()!=null) {
-                    final PColumn autoPartitionCol = 
parent.getPKColumns().get(MetaDataUtil.getAutoPartitionColIndex(parent));
-                    final Long autoPartitionNum = 
Long.valueOf(result.getAutoPartitionNum());
-                    columns.put(autoPartitionCol, new 
DelegateColumn(autoPartitionCol) {
-                        @Override
-                        public byte[] getViewConstant() {
-                            PDataType dataType = 
autoPartitionCol.getDataType();
-                            Object val = dataType.toObject(autoPartitionNum, 
PLong.INSTANCE);
-                            byte[] bytes = new byte [dataType.getByteSize() + 
1];
-                            dataType.toBytes(val, bytes, 0);
-                            return bytes;
-                        }
-                        @Override
-                        public boolean isViewReferenced() {
-                            return true;
-                        }
-                    });
-                    String viewPartitionClause = 
QueryUtil.getViewPartitionClause(MetaDataUtil.getAutoPartitionColumnName(parent),
 autoPartitionNum);
-                    if (viewStatement!=null) {
-                        viewStatement = viewStatement + " AND " + 
viewPartitionClause;
-                    }
-                    else {
-                        viewStatement = 
QueryUtil.getViewStatement(parent.getSchemaName().getString(), 
parent.getTableName().getString(), viewPartitionClause);
-                    }
-                }
-                PName newSchemaName = PNameFactory.newName(schemaName);
-                /*
-                 * It doesn't hurt for the PTable of views to have the 
cqCounter. However, views always rely on the
-                 * parent table's counter to dole out encoded column 
qualifiers. So setting the counter as NULL_COUNTER
-                 * for extra safety.
-                 */
-                EncodedCQCounter cqCounterToBe = tableType == PTableType.VIEW 
? NULL_COUNTER : cqCounter;
-                PTable table = new PTableImpl.Builder()
-                        .setType(tableType)
-                        .setState(indexState)
-                        .setTimeStamp(timestamp != null ? timestamp : 
result.getMutationTime())
-                        .setIndexDisableTimestamp(0L)
-                        .setSequenceNumber(PTable.INITIAL_SEQ_NUM)
-                        .setImmutableRows(isImmutableRows)
-                        .setViewStatement(viewStatement)
-                        .setDisableWAL(Boolean.TRUE.equals(disableWAL))
-                        .setMultiTenant(multiTenant)
-                        .setStoreNulls(storeNulls)
-                        .setViewType(viewType)
-                        .setViewIndexIdType(viewIndexIdType)
-                        .setViewIndexId(result.getViewIndexId())
-                        .setIndexType(indexType)
-                        .setTransactionProvider(transactionProvider)
-                        .setUpdateCacheFrequency(updateCacheFrequency)
-                        .setNamespaceMapped(isNamespaceMapped)
-                        .setAutoPartitionSeqName(autoPartitionSeq)
-                        .setAppendOnlySchema(isAppendOnlySchema)
-                        .setImmutableStorageScheme(immutableStorageScheme == 
null ?
-                                ImmutableStorageScheme.ONE_CELL_PER_COLUMN : 
immutableStorageScheme)
-                        .setQualifierEncodingScheme(encodingScheme == null ?
-                                QualifierEncodingScheme.NON_ENCODED_QUALIFIERS 
: encodingScheme)
-                        .setBaseColumnCount(baseTableColumnCount)
-                        .setEncodedCQCounter(cqCounterToBe)
-                        
.setUseStatsForParallelization(useStatsForParallelizationProp)
-                        .setExcludedColumns(ImmutableList.of())
-                        .setTenantId(tenantId)
-                        .setSchemaName(newSchemaName)
-                        .setTableName(PNameFactory.newName(tableName))
-                        .setPkName(pkName == null ? null : 
PNameFactory.newName(pkName))
-                        .setDefaultFamilyName(defaultFamilyName == null ?
-                                null : PNameFactory.newName(defaultFamilyName))
-                        .setRowKeyOrderOptimizable(rowKeyOrderOptimizable)
-                        .setBucketNum(saltBucketNum)
-                        .setIndexes(Collections.emptyList())
-                        .setParentSchemaName((parent == null) ? null : 
parent.getSchemaName())
-                        .setParentTableName((parent == null) ? null : 
parent.getTableName())
-                        .setPhysicalNames(physicalNames == null ?
-                                ImmutableList.of() : 
ImmutableList.copyOf(physicalNames))
-                        .setColumns(columns.values())
-                        .setViewTTL(viewTTL == null ? VIEW_TTL_NOT_DEFINED : 
viewTTL)
-                        .setViewTTLHighWaterMark(viewTTLHighWaterMark == null 
? MIN_VIEW_TTL_HWM : viewTTLHighWaterMark)
-                        .setViewModifiedUpdateCacheFrequency(tableType ==  
PTableType.VIEW &&
-                                parent != null &&
-                                parent.getUpdateCacheFrequency() != 
updateCacheFrequency)
-                        .setViewModifiedUseStatsForParallelization(tableType 
==  PTableType.VIEW &&
-                                parent != null &&
-                                parent.useStatsForParallelization()
-                                        != useStatsForParallelizationProp)
-                        .setViewModifiedViewTTL(tableType ==  PTableType.VIEW 
&&
-                                parent != null && viewTTL != null &&
-                                parent.getViewTTL() != viewTTL)
-                        .build();
-                result = new MetaDataMutationResult(code, 
result.getMutationTime(), table, true);
-                addTableToCache(result);
-                return table;
-            }
-        } finally {
-            connection.setAutoCommit(wasAutoCommit);
-            deleteMutexCells(parentPhysicalSchemaName, 
parentPhysicalTableName, acquiredColumnMutexSet);
+                // Cannot use SQLExecptionInfo here since not all mutation 
codes have their
+                // corresponding codes in the enum SQLExceptionCode
+                throw new SQLException("Exception occurred while creating 
table Mutation code, "
 
 Review comment:
   We're throwing this exception if none of the cases cover this mutation code, 
right? The exception message is incoorect in that case, since we're not 
creating mutation code. 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to