code: public List<NameType> executeQueryForDynamicColumn(String sql) throws Exception {
  
  		StringWriter sw = new StringWriter(100);
  		sw.append(sql);
  
  		String sqlForHeader = sw.toString();
  		LOG.info("call for chart dynamic columns = " + sqlForHeader);
  
  		ResultSet rs = null;
  		Statement stmt = null;
  		try {
  			if (isProcedureCall(sqlForHeader)) {
  				Dialect dialect = DialectUtil.getDialect(con);
  				CallableStatement cs = con.prepareCall("{" + sqlForHeader + "}");
  				stmt = cs;
  				if (dialect.hasProcedureWithCursor()) {
  					cs.registerOutParameter(1, dialect.getCursorSqlType());
  				}
  				rs = cs.executeQuery();
  				if (dialect.hasProcedureWithCursor()) {
  					rs = (ResultSet) (cs.getObject(1));
  				}
  			} else {
  				stmt = con.createStatement();
  				rs = stmt.executeQuery(sqlForHeader);
  			}
  			ResultSetMetaData rsmd = rs.getMetaData();
  			int columnCount = rsmd.getColumnCount();
  			if (columnCount != 2) {
  				throw new QueryException("Column query must have two data columns : column name and column legend.");
  			}
  
  			List<NameType> columnNames = new ArrayList<NameType>();
  			while (rs.next()) {
  				columnNames.add(new NameType(rs.getString(1), rs.getString(2)));
  			}
  			return columnNames;
  		} finally {
  			ConnectionUtil.closeResultSet(rs);
  			ConnectionUtil.closeStatement(stmt);
  		}
  
  	}
docs: return (column name, legend name) to set on chart