protected void reflect() {
    // fill in the sql for single statement procs
    if (m_catProc.getHasjava() == false) {
      try {
        Map<String, Field> stmtMap =
            ProcedureCompiler.getValidSQLStmts(null, m_procedureName, m_procedure.getClass(), true);
        Field f = stmtMap.get(VoltDB.ANON_STMT_NAME);
        assert (f != null);
        SQLStmt stmt = (SQLStmt) f.get(m_procedure);
        Statement statement = m_catProc.getStatements().get(VoltDB.ANON_STMT_NAME);
        stmt.sqlText = statement.getSqltext().getBytes(VoltDB.UTF8ENCODING);
        m_cachedSingleStmt.stmt = stmt;

        int numParams = m_catProc.getParameters().size();
        m_paramTypes = new Class<?>[numParams];
        m_paramTypeIsPrimitive = new boolean[numParams];
        m_paramTypeIsArray = new boolean[numParams];
        m_paramTypeComponentType = new Class<?>[numParams];

        for (ProcParameter param : m_catProc.getParameters()) {
          VoltType type = VoltType.get((byte) param.getType());
          if (type == VoltType.INTEGER) {
            type = VoltType.BIGINT;
          } else if (type == VoltType.SMALLINT) {
            type = VoltType.BIGINT;
          } else if (type == VoltType.TINYINT) {
            type = VoltType.BIGINT;
          } else if (type == VoltType.NUMERIC) {
            type = VoltType.FLOAT;
          }

          m_paramTypes[param.getIndex()] = type.classFromType();
          m_paramTypeIsPrimitive[param.getIndex()] = m_paramTypes[param.getIndex()].isPrimitive();
          m_paramTypeIsArray[param.getIndex()] = param.getIsarray();
          assert (m_paramTypeIsArray[param.getIndex()] == false);
          m_paramTypeComponentType[param.getIndex()] = null;

          // rtb: what is broken (ambiguous?) that is being patched here?
          // hack to fixup varbinary support for statement procedures
          if (m_paramTypes[param.getIndex()] == byte[].class) {
            m_paramTypeComponentType[param.getIndex()] = byte.class;
            m_paramTypeIsArray[param.getIndex()] = true;
          }
        }
      } catch (Exception e) {
        // shouldn't throw anything outside of the compiler
        e.printStackTrace();
      }
    } else {
      // parse the java run method
      Method[] methods = m_procedure.getClass().getDeclaredMethods();

      for (final Method m : methods) {
        String name = m.getName();
        if (name.equals("run")) {
          if (Modifier.isPublic(m.getModifiers()) == false) continue;
          m_procMethod = m;
          m_paramTypes = m.getParameterTypes();
          int tempParamTypesLength = m_paramTypes.length;

          m_paramTypeIsPrimitive = new boolean[tempParamTypesLength];
          m_paramTypeIsArray = new boolean[tempParamTypesLength];
          m_paramTypeComponentType = new Class<?>[tempParamTypesLength];
          for (int ii = 0; ii < tempParamTypesLength; ii++) {
            m_paramTypeIsPrimitive[ii] = m_paramTypes[ii].isPrimitive();
            m_paramTypeIsArray[ii] = m_paramTypes[ii].isArray();
            m_paramTypeComponentType[ii] = m_paramTypes[ii].getComponentType();
          }
        }
      }

      if (m_procMethod == null) {
        throw new RuntimeException(
            "No \"run\" method found in: " + m_procedure.getClass().getName());
      }
    }

    // iterate through the fields and deal with sql statements
    Map<String, Field> stmtMap = null;
    try {
      stmtMap =
          ProcedureCompiler.getValidSQLStmts(null, m_procedureName, m_procedure.getClass(), true);
    } catch (Exception e1) {
      // shouldn't throw anything outside of the compiler
      e1.printStackTrace();
      return;
    }

    Field[] fields = new Field[stmtMap.size()];
    int index = 0;
    for (Field f : stmtMap.values()) {
      fields[index++] = f;
    }
    for (final Field f : fields) {
      String name = f.getName();
      Statement s = m_catProc.getStatements().get(name);
      if (s != null) {
        try {
          /*
           * Cache all the information we need about the statements in this stored
           * procedure locally instead of pulling them from the catalog on
           * a regular basis.
           */
          SQLStmt stmt = (SQLStmt) f.get(m_procedure);

          // done in a static method in an abstract class so users don't call it
          initSQLStmt(stmt, s);

        } catch (IllegalArgumentException e) {
          e.printStackTrace();
        } catch (IllegalAccessException e) {
          e.printStackTrace();
        }
        // LOG.fine("Found statement " + name);
      }
    }
  }
Exemple #2
0
  static String generateProcedureRow(Procedure procedure) {
    StringBuilder sb = new StringBuilder();
    sb.append("<tr class='primaryrow'>");

    // column 1: procedure name
    String anchor = procedure.getTypeName().toLowerCase();
    sb.append(
        "<td style='white-space: nowrap'><i id='p-"
            + anchor
            + "--icon' class='icon-chevron-right'></i> <a href='#p-");
    sb.append(anchor).append("' id='p-").append(anchor).append("' class='togglex'>");
    sb.append(procedure.getTypeName());
    sb.append("</a></td>");

    // column 2: parameter types
    sb.append("<td>");
    List<ProcParameter> params =
        CatalogUtil.getSortedCatalogItems(procedure.getParameters(), "index");
    List<String> paramTypes = new ArrayList<String>();
    for (ProcParameter param : params) {
      String paramType = VoltType.get((byte) param.getType()).name();
      if (param.getIsarray()) {
        paramType += "[]";
      }
      paramTypes.add(paramType);
    }
    if (paramTypes.size() == 0) {
      sb.append("<i>None</i>");
    }
    sb.append(StringUtils.join(paramTypes, ", "));
    sb.append("</td>");

    // column 3: partitioning
    sb.append("<td>");
    if (procedure.getSinglepartition()) {
      tag(sb, "success", "Single");
    } else {
      tag(sb, "warning", "Multi");
    }
    sb.append("</td>");

    // column 4: read/write
    sb.append("<td>");
    if (procedure.getReadonly()) {
      tag(sb, "success", "Read");
    } else {
      tag(sb, "warning", "Write");
    }
    sb.append("</td>");

    // column 5: access
    sb.append("<td>");
    List<String> groupNames = new ArrayList<String>();
    for (GroupRef groupRef : procedure.getAuthgroups()) {
      groupNames.add(groupRef.getGroup().getTypeName());
    }
    if (groupNames.size() == 0) {
      sb.append("<i>None</i>");
    }
    sb.append(StringUtils.join(groupNames, ", "));
    sb.append("</td>");

    // column 6: attributes
    sb.append("<td>");
    if (procedure.getHasjava()) {
      tag(sb, "info", "Java");
    } else {
      tag(sb, null, "Single-Stmt");
    }
    boolean isND = false;
    int scanCount = 0;
    for (Statement stmt : procedure.getStatements()) {
      scanCount += stmt.getSeqscancount();
      if (!stmt.getIscontentdeterministic() || !stmt.getIsorderdeterministic()) {
        isND = false;
      }
    }
    if (isND) {
      tag(sb, "inverse", "Determinism");
    }
    if (scanCount > 0) {
      tag(sb, "important", "Scans");
    }
    sb.append("</td>");

    sb.append("</tr>\n");

    // BUILD THE DROPDOWN FOR THE STATEMENT/DETAIL TABLE

    sb.append(
        "<tr class='tablesorter-childRow'><td class='invert' colspan='6' id='p-"
            + procedure.getTypeName().toLowerCase()
            + "--dropdown'>\n");

    // output partitioning parameter info
    if (procedure.getSinglepartition()) {
      String pTable = procedure.getPartitioncolumn().getParent().getTypeName();
      String pColumn = procedure.getPartitioncolumn().getTypeName();
      int pIndex = procedure.getPartitionparameter();

      sb.append(
          String.format(
              "<p>Partitioned on parameter %d which maps to column %s"
                  + " of table <a class='invert' href='#s-%s'>%s</a>.</p>",
              pIndex, pColumn, pTable, pTable));
    }

    // output what schema this interacts with
    ProcedureAnnotation annotation = (ProcedureAnnotation) procedure.getAnnotation();
    if (annotation != null) {
      // make sure tables appear in only one category
      annotation.tablesRead.removeAll(annotation.tablesUpdated);

      if (annotation.tablesRead.size() > 0) {
        sb.append("<p>Read-only access to tables: ");
        List<String> tables = new ArrayList<String>();
        for (Table table : annotation.tablesRead) {
          tables.add("<a href='#s-" + table.getTypeName() + "'>" + table.getTypeName() + "</a>");
        }
        sb.append(StringUtils.join(tables, ", "));
        sb.append("</p>");
      }
      if (annotation.tablesUpdated.size() > 0) {
        sb.append("<p>Read/Write access to tables: ");
        List<String> tables = new ArrayList<String>();
        for (Table table : annotation.tablesUpdated) {
          tables.add("<a href='#s-" + table.getTypeName() + "'>" + table.getTypeName() + "</a>");
        }
        sb.append(StringUtils.join(tables, ", "));
        sb.append("</p>");
      }
      if (annotation.indexesUsed.size() > 0) {
        sb.append("<p>Uses indexes: ");
        List<String> indexes = new ArrayList<String>();
        for (Index index : annotation.indexesUsed) {
          Table table = (Table) index.getParent();
          indexes.add(
              "<a href='#s-"
                  + table.getTypeName()
                  + "-"
                  + index.getTypeName()
                  + "'>"
                  + index.getTypeName()
                  + "</a>");
        }
        sb.append(StringUtils.join(indexes, ", "));
        sb.append("</p>");
      }
    }

    sb.append(generateStatementsTable(procedure));

    sb.append("</td></tr>\n");

    return sb.toString();
  }