/** Executes the current statement, and handles any SQLException. */ public void execute() { assert state == State.FRESH : "cannot re-execute"; state = State.ACTIVE; String status = "failed"; Statement statement = null; try { this.jdbcConnection = dataSource.getConnection(); querySemaphore.enter(); haveSemaphore = true; // Trace start of execution. if (RolapUtil.SQL_LOGGER.isDebugEnabled()) { StringBuilder sqllog = new StringBuilder(); sqllog.append(id).append(": ").append(locus.component).append(": executing sql ["); if (sql.indexOf('\n') >= 0) { // SQL appears to be formatted as multiple lines. Make it // start on its own line. sqllog.append("\n"); } sqllog.append(sql); sqllog.append(']'); RolapUtil.SQL_LOGGER.debug(sqllog.toString()); } // Execute hook. RolapUtil.ExecuteQueryHook hook = RolapUtil.getHook(); if (hook != null) { hook.onExecuteQuery(sql); } startTimeNanos = System.nanoTime(); startTimeMillis = System.currentTimeMillis(); if (resultSetType < 0 || resultSetConcurrency < 0) { statement = jdbcConnection.createStatement(); } else { statement = jdbcConnection.createStatement(resultSetType, resultSetConcurrency); } if (maxRows > 0) { statement.setMaxRows(maxRows); } // First make sure to register with the execution instance. locus.execution.registerStatement(locus, statement); locus .getServer() .getMonitor() .sendEvent( new SqlStatementStartEvent( startTimeMillis, id, locus, sql, getPurpose(), getCellRequestCount())); this.resultSet = statement.executeQuery(sql); // skip to first row specified in request this.state = State.ACTIVE; if (firstRowOrdinal > 0) { if (resultSetType == ResultSet.TYPE_FORWARD_ONLY) { for (int i = 0; i < firstRowOrdinal; ++i) { if (!this.resultSet.next()) { this.state = State.DONE; break; } } } else { if (!this.resultSet.absolute(firstRowOrdinal)) { this.state = State.DONE; } } } long timeMillis = System.currentTimeMillis(); long timeNanos = System.nanoTime(); final long executeNanos = timeNanos - startTimeNanos; final long executeMillis = executeNanos / 1000000; Util.addDatabaseTime(executeMillis); status = ", exec " + executeMillis + " ms"; locus .getServer() .getMonitor() .sendEvent( new SqlStatementExecuteEvent(timeMillis, id, locus, sql, getPurpose(), executeNanos)); // Compute accessors. They ensure that we use the most efficient // method (e.g. getInt, getDouble, getObject) for the type of the // column. Even if you are going to box the result into an object, // it is better to use getInt than getObject; the latter might // return something daft like a BigDecimal (does, on the Oracle JDBC // driver). accessors.clear(); for (Type type : guessTypes()) { accessors.add(createAccessor(accessors.size(), type)); } } catch (Throwable e) { status = ", failed (" + e + ")"; Util.close(resultSet, statement, jdbcConnection); if (haveSemaphore) { haveSemaphore = false; querySemaphore.leave(); } if (e instanceof Error) { throw (Error) e; } else { throw handle(e); } } finally { RolapUtil.SQL_LOGGER.debug(id + ": " + status); if (RolapUtil.LOGGER.isDebugEnabled()) { RolapUtil.LOGGER.debug(locus.component + ": executing sql [" + sql + "]" + status); } } }