@Override public PostgresStatementResult execute( PostgresQueryContext context, QueryBindings bindings, int maxrows) throws IOException { PostgresServerSession server = context.getServer(); server.getSessionMonitor().countEvent(StatementTypes.OTHER_STMT); PostgresMessenger messenger = server.getMessenger(); ServerValueEncoder encoder = server.getValueEncoder(); int nrows = 0; for (String row : explanation) { messenger.beginMessage(PostgresMessages.DATA_ROW_TYPE.code()); messenger.writeShort(1); ByteArrayOutputStream bytes = encoder.encodePObject(row, colType, false); messenger.writeInt(bytes.size()); messenger.writeByteStream(bytes); messenger.sendMessage(); nrows++; if ((maxrows > 0) && (nrows >= maxrows)) break; } return commandComplete("EXPLAIN " + nrows, nrows); }
@Override public void sendDescription(PostgresQueryContext context, boolean always, boolean params) throws IOException { PostgresServerSession server = context.getServer(); PostgresMessenger messenger = server.getMessenger(); if (params) { messenger.beginMessage(PostgresMessages.PARAMETER_DESCRIPTION_TYPE.code()); messenger.writeShort(0); messenger.sendMessage(); } messenger.beginMessage(PostgresMessages.ROW_DESCRIPTION_TYPE.code()); messenger.writeShort(1); messenger.writeString(colName); // attname messenger.writeInt(0); // attrelid messenger.writeShort(0); // attnum messenger.writeInt(colType.getOid()); // atttypid messenger.writeShort(colType.getLength()); // attlen messenger.writeInt(colType.getModifier()); // atttypmod messenger.writeShort(0); messenger.sendMessage(); }
@Override public PostgresStatement finishGenerating( PostgresServerSession server, String sql, StatementNode stmt, List<ParameterNode> params, int[] paramTypes) { ExplainPlanContext context = new ExplainPlanContext(compiler, new PostgresQueryContext(server)); ExplainStatementNode explainStmt = (ExplainStatementNode) stmt; StatementNode innerStmt = explainStmt.getStatement(); if (params == null) params = new ParameterFinder().find(innerStmt); Explainable explainable; if (innerStmt instanceof CallStatementNode) { explainable = PostgresCallStatementGenerator.explainable( server, (CallStatementNode) innerStmt, params, paramTypes); } else { BasePlannable result = compiler.compile((DMLStatementNode) innerStmt, params, context); explainable = result.getPlannable(); } List<String> explain; if (compiler instanceof PostgresJsonCompiler) { JsonFormatter f = new JsonFormatter(); explain = Collections.singletonList( f.format(explainable.getExplainer(context.getExplainContext()))); } else { DefaultFormatter.LevelOfDetail detail; switch (explainStmt.getDetail()) { case BRIEF: detail = DefaultFormatter.LevelOfDetail.BRIEF; break; default: case NORMAL: detail = DefaultFormatter.LevelOfDetail.NORMAL; break; case VERBOSE: detail = DefaultFormatter.LevelOfDetail.VERBOSE; break; } DefaultFormatter f = new DefaultFormatter(server.getDefaultSchemaName(), detail); explain = f.format(explainable.getExplainer(context.getExplainContext())); } init(explain); compiler = null; return this; }