final PredicatePairs cset,
final AbstractPlanNode root_node,
final boolean convert_params,
final Table... catalog_tables) throws Exception {
assert (catalog_stmt.getQuerytype() == QueryType.INSERT.getValue());
final Database catalog_db = CatalogUtil.getDatabase(catalog_stmt);
final List<List<CatalogType>> materialize_elements = new ArrayList<List<CatalogType>>();
// Find the MaterializePlanNode that feeds into the Insert
// This will have the list of columns that will be used to insert into
// the table
new PlanNodeTreeWalker() {
@Override
protected void callback(final AbstractPlanNode node) {
// We should find the Materialize node before the Insert
if (node instanceof MaterializePlanNode) {
for (Integer column_guid : node.getOutputColumnGUIDs()) {
PlanColumn column = PlannerContext.singleton().get(column_guid);
assert (column != null);
AbstractExpression exp = column.getExpression();
// Now extract the CatalogType objects that are being
// referenced by this materialization column
final List<CatalogType> catalog_refs = new ArrayList<CatalogType>();
new ExpressionTreeWalker() {
@Override
protected void callback(AbstractExpression exp) {
if (!(exp instanceof AbstractValueExpression))
return;
CatalogType element = null;
switch (exp.getExpressionType()) {
case VALUE_PARAMETER: {
int param_idx = ((ParameterValueExpression) exp).getParameterId();
element = catalog_stmt.getParameters().get(param_idx);
if (element == null) {
LOG.warn("ERROR: Unable to find Parameter object in catalog [" + ((ParameterValueExpression) exp).getParameterId() + "]");
this.stop();
}
// We want to use the ProcParameter instead of the StmtParameter
// It's not an error if the StmtParameter is not mapped to a
// ProcParameter
if (convert_params && ((StmtParameter) element).getProcparameter() != null) {
LOG.debug(element + "(" + element + ") --> ProcParameter[" + element.getField("procparameter") + "]");
element = ((StmtParameter) element).getProcparameter();
}
break;
}
case VALUE_TUPLE_ADDRESS:
case VALUE_TUPLE: {
// This shouldn't happen, but it is nice
// to be told if it does...
LOG.warn("Unexpected " + exp.getClass().getSimpleName() + " node when examining " + node.getClass().getSimpleName() + " for " + catalog_stmt);
break;
}
default: {
// Do nothing...
}
} // SWITCH
if (element != null) {
catalog_refs.add(element);
LOG.debug(node + ": " + catalog_refs);
}
return;
}
}.traverse(exp);
materialize_elements.add(catalog_refs);
} // FOR
// InsertPlanNode
} else if (node instanceof InsertPlanNode) {
InsertPlanNode insert_node = (InsertPlanNode) node;
Table catalog_tbl = catalog_db.getTables().get(insert_node.getTargetTableName());
// We only support when the Materialize node is inserting
// data into all columns
if (materialize_elements.size() != catalog_tbl.getColumns().size()) {
String msg = String.format("%s has %d columns but the MaterializePlanNode has %d output columns", catalog_tbl, catalog_tbl.getColumns().size(), materialize_elements.size());