package edu.brown.gui.catalog; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.apache.log4j.Logger; import org.voltdb.VoltType; import org.voltdb.catalog.Catalog; import org.voltdb.catalog.CatalogType; import org.voltdb.catalog.Column; import org.voltdb.catalog.ColumnRef; import org.voltdb.catalog.Constraint; import org.voltdb.catalog.Database; import org.voltdb.catalog.Host; import org.voltdb.catalog.Index; import org.voltdb.catalog.MaterializedViewInfo; import org.voltdb.catalog.Partition; import org.voltdb.catalog.PlanFragment; import org.voltdb.catalog.ProcParameter; import org.voltdb.catalog.Procedure; import org.voltdb.catalog.Site; import org.voltdb.catalog.Statement; import org.voltdb.catalog.StmtParameter; import org.voltdb.catalog.Table; import org.voltdb.catalog.CatalogType.UnresolvedInfo; import org.voltdb.plannodes.AbstractPlanNode; import org.voltdb.types.ConstraintType; import org.voltdb.types.IndexType; import org.voltdb.types.QueryType; import org.voltdb.utils.Encoder; import edu.brown.catalog.CatalogUtil; import edu.brown.catalog.conflicts.ConflictSetUtil; import edu.brown.logging.LoggerUtil; import edu.brown.logging.LoggerUtil.LoggerBoolean; import edu.brown.plannodes.PlanNodeUtil; import edu.brown.utils.CollectionUtil; import edu.brown.utils.SQLFormatter; import edu.brown.utils.StringUtil; /** * Catalog Attributes Pretty Printer * @author pavlo */ public class CatalogAttributeText { private static final Logger LOG = Logger.getLogger(CatalogAttributeText.class); private static final LoggerBoolean debug = new LoggerBoolean(); private static final LoggerBoolean trace = new LoggerBoolean(); static { LoggerUtil.attachObserver(LOG, debug, trace); } final Catalog catalog; public CatalogAttributeText(Catalog catalog) { this.catalog = catalog; } /** * Generate a formatted print out of the attributes for a given catalog object * @param catalog_obj */ @SuppressWarnings("unchecked") public String getAttributesText(CatalogType catalog_obj) { Map<String, Object> m[] = (Map<String, Object>[])new Map[1]; m[0] = new LinkedHashMap<String, Object>(); // StringBuilder buffer = new StringBuilder(); // buffer.append("guid: ").append(catalog_obj.getGuid()).append("\n"); m[0].put("relativeIndex", catalog_obj.getRelativeIndex()); m[0].put("nodeVersion", catalog_obj.getNodeVersion()); // Default Output if ((catalog_obj instanceof Database) == false) { Collection<String> skip_fields = CollectionUtil.addAll(new HashSet<String>(), "exptree", "fullplan", "ms_exptree", "ms_fullplan", "plannodetree", "sqltext"); Collection<String> catalog_fields = CollectionUtil.addAll(new HashSet<String>(), "partition_column", "partitioncolumn", "foreignkeytable", "matviewsource"); if (catalog_obj instanceof Constraint) { catalog_fields.add("index"); } else if (catalog_obj instanceof Site) { catalog_fields.add("host"); catalog_fields.add("partition"); } // Show catalog type Set<Class<? extends CatalogType>> show_type = new HashSet<Class<? extends CatalogType>>(); show_type.add(Host.class); show_type.add(Site.class); show_type.add(Partition.class); for (String field : catalog_obj.getFields()) { if (skip_fields.contains(field)) { if (LOG.isDebugEnabled()) LOG.warn(String.format("Skipping %s.%s", catalog_obj.getClass().getSimpleName(), field)); continue; } // Default Object value = catalog_obj.getField(field); m[0].put(field, value); // Specialized Output if (value != null && catalog_fields.contains(field)) { CatalogType catalog_item = null; if (value instanceof CatalogType) { catalog_item = (CatalogType)value; } else if (value instanceof CatalogType.UnresolvedInfo) { catalog_item = catalog.getItemForRef(((UnresolvedInfo)value).path); } else { assert(false) : "Unexpected value '" + value + "' for field '" + field + "'"; } if (catalog_item != null) { boolean include_class = show_type.contains(catalog_item.getClass()); m[0].put(field, CatalogUtil.getDisplayName(catalog_item, include_class)); } else { m[0].put(field, catalog_item); } } // CONSTRAINT else if (catalog_obj instanceof Constraint) { if (field == "type") { m[0].put(field, ConstraintType.get((Integer)value)); } } // INDEX else if (catalog_obj instanceof Index) { if (field == "type") { m[0].put(field, IndexType.get((Integer)value)); } } // STATEMENT else if (catalog_obj instanceof Statement) { if (field == "querytype") { m[0].put(field, QueryType.get((Integer)value)); } } // COLUMN / STMTPARAMETER / PROCPARAMETER else if (catalog_obj instanceof Column || catalog_obj instanceof StmtParameter || catalog_obj instanceof ProcParameter) { String keys[] = { "type", "sqltype", "javatype", "defaultvaluetype" }; for (String key : keys) { if (field == key) { m[0].put(field, VoltType.get(((Integer)value).byteValue()).name()); break; } } // FOR if (field.equals("procparameter")) { ProcParameter proc_param = ((StmtParameter)catalog_obj).getProcparameter(); if (proc_param != null) { m[0].put(field, proc_param.fullName()); } } } } // FOR } else { m[0].put("project", ((Database)catalog_obj).getProject()); } // INDEX if (catalog_obj instanceof Index) { Index catalog_idx = (Index)catalog_obj; Collection<Column> cols = CatalogUtil.getColumns(CatalogUtil.getSortedCatalogItems(catalog_idx.getColumns(), "index")); m[0].put("columns", CatalogUtil.getDisplayNames(cols)); } // CONSTRAINT else if (catalog_obj instanceof Constraint) { Constraint catalog_const = (Constraint)catalog_obj; Collection<Column> cols = null; if (catalog_const.getType() == ConstraintType.FOREIGN_KEY.getValue()) { cols = CatalogUtil.getColumns(catalog_const.getForeignkeycols()); } else { Index catalog_idx = catalog_const.getIndex(); cols = CatalogUtil.getColumns(catalog_idx.getColumns()); } m[0].put("columns", CatalogUtil.getDisplayNames(cols)); } // COLUMN else if (catalog_obj instanceof Column) { Column catalog_col = (Column)catalog_obj; Collection<Constraint> consts = CatalogUtil.getConstraints(catalog_col.getConstraints()); m[0].put("constraints", CatalogUtil.getDisplayNames(consts)); } // MATERIALIZEDVIEWINFO else if (catalog_obj instanceof MaterializedViewInfo) { MaterializedViewInfo catalog_view = (MaterializedViewInfo)catalog_obj; Collection<ColumnRef> cols = catalog_view.getGroupbycols(); m[0].put("groupbycols", CatalogUtil.debug(CatalogUtil.getColumns(cols))); } // PROCEDURE else if (catalog_obj instanceof Procedure) { Procedure catalog_proc = (Procedure)catalog_obj; Collection<Procedure> rwConflicts = ConflictSetUtil.getReadWriteConflicts(catalog_proc); Collection<Procedure> wwConflicts = ConflictSetUtil.getWriteWriteConflicts(catalog_proc); if (rwConflicts.size() > 0 || wwConflicts.size() > 0) { Map<String, Object> orig_m = m[0]; m = (Map<String, Object>[])new Map[2]; m[0] = orig_m; m[1] = new TreeMap<String, Object>(); Collection<Procedure> conflicts[] = (Collection<Procedure>[])new Collection<?>[] { rwConflicts, wwConflicts }; String labels[] = { "Read-Write", "Write-Write" }; for (int i = 0; i < labels.length; i++) { String value = ""; Collection<Procedure> c = conflicts[i]; if (c.size() > 0) { List<String> conflictLabels = new ArrayList<String>(CatalogUtil.getDisplayNames(rwConflicts)); Collections.sort(conflictLabels); value = StringUtil.join("\n", conflictLabels); } else { value ="<NONE>"; } m[1].put(labels[i] + " Conflicts", value + "\n"); } // FOR } } StringBuilder sb = new StringBuilder(StringUtil.formatMaps(m)); // DATABASE if (catalog_obj instanceof Database) { sb.append(StringUtil.SINGLE_LINE); sb.append(Encoder.hexDecodeToString(((Database)catalog_obj).getSchema())); } // PLANFRAGMENT else if (catalog_obj instanceof PlanFragment) { PlanFragment catalog_frgmt = (PlanFragment)catalog_obj; try { AbstractPlanNode node = PlanNodeUtil.getPlanNodeTreeForPlanFragment(catalog_frgmt); sb.append(StringUtil.SINGLE_LINE); sb.append(PlanNodeUtil.debug(node)); } catch (Exception e) { e.printStackTrace(); } } // TABLE else if (catalog_obj instanceof Table) { sb.append(StringUtil.SINGLE_LINE); Table catalog_tbl = (Table)catalog_obj; // MATERIALIZED VIEW if (catalog_tbl.getMaterializer() != null) { Table parent = catalog_tbl.getMaterializer(); MaterializedViewInfo catalog_view = parent.getViews().get(catalog_tbl.getName()); assert(catalog_view != null) : "Unexpected null MaterializedViewInfo '" + catalog_tbl.getName() + "'"; sb.append(MaterializedViewInfo.class.getSimpleName()).append("\n"); sb.append(this.getAttributesText(catalog_view)); SQLFormatter f = new SQLFormatter(catalog_view.getSqltext()); sb.append(StringUtil.SINGLE_LINE); sb.append("\n").append(f.format()).append("\n"); } else { String schema = CatalogUtil.toSchema(catalog_tbl); sb.append("\n").append(schema).append("\n"); } } // Statement else if (catalog_obj instanceof Statement) { Statement catalog_stmt = (Statement)catalog_obj; SQLFormatter f = new SQLFormatter(catalog_stmt.getSqltext()); sb.append(StringUtil.SINGLE_LINE); sb.append("\n").append(f.format()).append("\n"); } return (sb.toString()); } }