public void setTypeSizeAndInBytes(SchemaColumn typeSource) { setValueType(typeSource.getType()); setValueSize(typeSource.getSize()); m_inBytes = typeSource.getExpression().getInBytes(); }
/** * Compile and cache the statement and plan and return the final plan graph. * * @param sql * @param paramCount */ public List<AbstractPlanNode> compile( String sql, int paramCount, String joinOrder, Object partitionParameter, boolean inferSP, boolean lockInSP) { Statement catalogStmt = proc.getStatements().add("stmt-" + String.valueOf(compileCounter++)); catalogStmt.setSqltext(sql); catalogStmt.setSinglepartition(partitionParameter != null); catalogStmt.setBatched(false); catalogStmt.setParamnum(paramCount); // determine the type of the query QueryType qtype = QueryType.SELECT; catalogStmt.setReadonly(true); if (sql.toLowerCase().startsWith("insert")) { qtype = QueryType.INSERT; catalogStmt.setReadonly(false); } if (sql.toLowerCase().startsWith("update")) { qtype = QueryType.UPDATE; catalogStmt.setReadonly(false); } if (sql.toLowerCase().startsWith("delete")) { qtype = QueryType.DELETE; catalogStmt.setReadonly(false); } catalogStmt.setQuerytype(qtype.getValue()); // name will look like "basename-stmt-#" String name = catalogStmt.getParent().getTypeName() + "-" + catalogStmt.getTypeName(); DatabaseEstimates estimates = new DatabaseEstimates(); TrivialCostModel costModel = new TrivialCostModel(); PartitioningForStatement partitioning = new PartitioningForStatement(partitionParameter, inferSP, lockInSP); QueryPlanner planner = new QueryPlanner( catalogStmt.getSqltext(), catalogStmt.getTypeName(), catalogStmt.getParent().getTypeName(), catalog.getClusters().get("cluster"), db, partitioning, hsql, estimates, false, StatementCompiler.DEFAULT_MAX_JOIN_TABLES, costModel, null, joinOrder); CompiledPlan plan = null; planner.parse(); plan = planner.plan(); assert (plan != null); // Input Parameters // We will need to update the system catalogs with this new information // If this is an adhoc query then there won't be any parameters for (int i = 0; i < plan.parameters.length; ++i) { StmtParameter catalogParam = catalogStmt.getParameters().add(String.valueOf(i)); catalogParam.setJavatype(plan.parameters[i].getValue()); catalogParam.setIndex(i); } // Output Columns int index = 0; for (SchemaColumn col : plan.columns.getColumns()) { Column catColumn = catalogStmt.getOutput_columns().add(String.valueOf(index)); catColumn.setNullable(false); catColumn.setIndex(index); catColumn.setName(col.getColumnName()); catColumn.setType(col.getType().getValue()); catColumn.setSize(col.getSize()); index++; } List<PlanNodeList> nodeLists = new ArrayList<PlanNodeList>(); nodeLists.add(new PlanNodeList(plan.rootPlanGraph)); if (plan.subPlanGraph != null) { nodeLists.add(new PlanNodeList(plan.subPlanGraph)); } // Store the list of parameters types and indexes in the plan node list. List<Pair<Integer, VoltType>> parameters = nodeLists.get(0).getParameters(); for (int i = 0; i < plan.parameters.length; ++i) { Pair<Integer, VoltType> parameter = new Pair<Integer, VoltType>(i, plan.parameters[i]); parameters.add(parameter); } // Now update our catalog information // HACK: We're using the node_tree's hashCode() as it's name. It would be really // nice if the Catalog code give us an guid without needing a name first... String json = null; try { JSONObject jobj = new JSONObject(nodeLists.get(0).toJSONString()); json = jobj.toString(4); } catch (JSONException e2) { // TODO Auto-generated catch block e2.printStackTrace(); System.exit(-1); } // // We then stick a serialized version of PlanNodeTree into a PlanFragment // try { BuildDirectoryUtils.writeFile("statement-plans", name + "_json.txt", json); BuildDirectoryUtils.writeFile( "statement-plans", name + ".dot", nodeLists.get(0).toDOTString("name")); } catch (Exception e) { e.printStackTrace(); } List<AbstractPlanNode> plannodes = new ArrayList<AbstractPlanNode>(); for (PlanNodeList nodeList : nodeLists) { plannodes.add(nodeList.getRootPlanNode()); } m_currentPlan = plan; return plannodes; }