Too much copy/paste here. How about this instead:
* Derive CreateIndexStatement from CreateTableStatement.
* Add methods on CreateTableStatement to abstract getting the column type (since this is what's different for an index table)
* Specialize CreateIndexStatement.getPrimaryKeyConstraint() to include any columns from the data table that aren't included in the index
* Add a method on CreateTableStatement to addAdditionalMutations. This would be a noop for CreateTableStatement, but for CreateIndexStatement would add the row that links the table and index.
* Add a method on CreateTableStatement that creates the PostDDLCompiler. For an index, you'd specialize this to run your index populatation code.

Then you can just call MetaDataClient.createTable with your CreateIndexStatement. The code on the server side in MetaDataEndPointImpl should be the same for creating an index versus creating a table. The only difference will be that if tableType==PTableType.INDEX, you'd invalidate the table row cache entry (which you could formulate because you have the row that links the data table with the index table)