[
https://issues.apache.org/jira/browse/PHOENIX-2058?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14608634#comment-14608634
]
James Taylor commented on PHOENIX-2058:
---------------------------------------
The check should be included in the for loop at MetaDataEndPointImpl:1616:
{code}
for (Mutation m : tableMetadata) {
byte[][] rkmd = new byte[5][];
int pkCount = getVarChars(m.getRow(), rkmd);
if (m instanceof Put && pkCount > COLUMN_NAME_INDEX
&& Bytes.compareTo(schemaName, rkmd[SCHEMA_NAME_INDEX])
== 0
&& Bytes.compareTo(tableName, rkmd[TABLE_NAME_INDEX])
== 0) {
Put p = (Put)m;
byte[] columnKey = ByteUtil.concat(viewKey,
QueryConstants.SEPARATOR_BYTE_ARRAY, rkmd[COLUMN_NAME_INDEX]);
if (rkmd[FAMILY_NAME_INDEX] != null) {
columnKey = ByteUtil.concat(columnKey,
QueryConstants.SEPARATOR_BYTE_ARRAY, rkmd[FAMILY_NAME_INDEX]);
}
Put viewColumnDefinitionPut = new Put(columnKey,
clientTimeStamp);
for (Cell cell :
p.getFamilyCellMap().values().iterator().next()) {
viewColumnDefinitionPut.add(CellUtil.createCell(columnKey,
CellUtil.cloneFamily(cell),
CellUtil.cloneQualifier(cell),
cell.getTimestamp(), cell.getTypeByte(),
CellUtil.cloneValue(cell)));
}
{code}
The view is the PTable that represents the view that we're adding the column
to. The for loop is looping through the mutations from the base table being
added. First, outside the loop, you can check if the view already has the
column that's being added using the following code:
{code}
PColumn existingViewColumn = null;
try {
// Maybe deserving of a new SchemaUtil.getColumnByName(byte[] familyName,
String columnName) function
String columnName = Bytes.toString(rkmd[COLUMN_NAME_INDEX]);
existingViewColumn = rkmd[FAMILY_NAME_INDEX] == null
? view.getPKColumn(columnName)
: view.getColumnFamily(rkmd[FAMILY_NAME_INDEX]).getColumn(columnName);
} catch (MetaDataEntityNotFoundException e) {} // Ignore - means column family
or column name don't exist
{code}
Within this loop, only if existingViewColumn != null, you'd want to check the
CellUtil.cloneQualifier(cell) being equal to DATA_TYPE_BYTES (this is the
sqlTypeID that you can use to get the PDataType), COLUMN_SIZE_BYTES (this is
maxLength), DECIMAL_DIGITS_BYTES (this is scale), and KEY_SEQ_BYTES (this is
the slot position within the PK which has to match, but only if the column
being added is a PK column).
Then, outside the loop (or even inside of it when possible), do the checks
mentioned in the description of this JIRA. If one of the checks fails, just
return the following (change the return type of addRowsToChildViews to
MetaDataMutationResult) and return early in the caller if you get a non null
MetaDataMutationResult from addRowsToChildViews:
{code}
return new
MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION,
EnvironmentEdgeManager.currentTimeMillis(), null);
{code}
We can eventually do a better job of returning a more specific exception, but
this is ok for now.
> Check for existence and compatibility of columns being added in view
> --------------------------------------------------------------------
>
> Key: PHOENIX-2058
> URL: https://issues.apache.org/jira/browse/PHOENIX-2058
> Project: Phoenix
> Issue Type: Bug
> Reporter: James Taylor
> Assignee: Thomas D'Silva
>
> One check I realized we're not doing, but need to do, is ensuring that the
> column being added by the base table doesn't already exist in the view. If
> the column does already exist, ideally we can allow the addition to the base
> table if the type matches and the scale is null or >= existing scale and the
> maxLength is null or >= existing maxLength. Also, if a column is a PK column
> and it already exists in the view, the position in the PK must match.
> The fact that we've materialized a PTable for the view should make the
> addition of this check easier.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)