public ResultSet getFunctionColumns()

in src/main/java/com/amazon/redshift/jdbc/RedshiftDatabaseMetaData.java [4549:5144]


  public ResultSet getFunctionColumns(String catalog, String schemaPattern,
      String functionNamePattern, String columnNamePattern)
      throws SQLException {
    int columns = 17;

    if (RedshiftLogger.isEnable())
    	connection.getLogger().logFunction(true, catalog, schemaPattern, functionNamePattern, columnNamePattern);
    
/*    Field[] f = new Field[columns];
    List<Tuple> v = new ArrayList<Tuple>();

    f[0] = new Field("FUNCTION_CAT", Oid.VARCHAR);
    f[1] = new Field("FUNCTION_SCHEM", Oid.VARCHAR);
    f[2] = new Field("FUNCTION_NAME", Oid.VARCHAR);
    f[3] = new Field("COLUMN_NAME", Oid.VARCHAR);
    f[4] = new Field("COLUMN_TYPE", Oid.INT2);
    f[5] = new Field("DATA_TYPE", Oid.INT2);
    f[6] = new Field("TYPE_NAME", Oid.VARCHAR);
    f[7] = new Field("PRECISION", Oid.INT2);
    f[8] = new Field("LENGTH", Oid.INT4);
    f[9] = new Field("SCALE", Oid.INT2);
    f[10] = new Field("RADIX", Oid.INT2);
    f[11] = new Field("NULLABLE", Oid.INT2);
    f[12] = new Field("REMARKS", Oid.VARCHAR);
    f[13] = new Field("CHAR_OCTET_LENGTH", Oid.INT4);
    f[14] = new Field("ORDINAL_POSITION", Oid.INT4);
    f[15] = new Field("IS_NULLABLE", Oid.VARCHAR);
    f[16] = new Field("SPECIFIC_NAME", Oid.VARCHAR);
*/    

/*    String sql;
    	sql = "SELECT n.nspname,p.proname,p.prorettype,p.proargtypes, t.typtype,t.typrelid, "
        + " p.proargnames, p.proargmodes, p.proallargtypes, p.prooid "
        + " FROM pg_catalog.pg_proc_info p, pg_catalog.pg_namespace n, pg_catalog.pg_type t "
        + " WHERE p.pronamespace=n.oid AND p.prorettype=t.oid ";
*/
	final String unknownColumnSize = "2147483647";
	final String superMaxLength = "4194304 ";
	final String varbyteMaxLength = "1000000 ";
	
	StringBuilder functionColumnQuery = new StringBuilder();
	
	functionColumnQuery.append(
	    "SELECT PROCEDURE_CAT AS FUNCTION_CAT, "
			+ " PROCEDURE_SCHEM AS FUNCTION_SCHEM, "
	    + " PROCEDURE_NAME AS FUNCTION_NAME,"
			+ " COLUMN_NAME, "
	    + " COLUMN_TYPE, "
			+ " DATA_TYPE, "
	    + " TYPE_NAME, "
			+ " COLUMN_SIZE AS PRECISION, "
	    + " LENGTH , "
			+ " DECIMAL_DIGITS AS SCALE, "
	    + " NUM_PREC_RADIX AS RADIX, "
			+ " NULLABLE, "
	    + " REMARKS, "
	    + " CHAR_OCTET_LENGTH, "
	    + " ORDINAL_POSITION, "
	    + " IS_NULLABLE, "
	    + " SPECIFIC_NAME  "
	    + " FROM (");
	
	functionColumnQuery.append("SELECT current_database() AS PROCEDURE_CAT, "
	        + " n.nspname as PROCEDURE_SCHEM, "
	        + " p.proname AS PROCEDURE_NAME, "
	        + " CAST(CASE ((array_upper(proargnames, 0) - array_lower(proargnames, 0)) > 0) "
	        + " WHEN 't' THEN proargnames[array_upper(proargnames, 1)] "
	        + " ELSE '' "
	        + " END AS VARCHAR(256)) AS COLUMN_NAME, "
	
	        + " CAST(CASE p.proretset "
	        + " WHEN 't' THEN 3 "
	        + " ELSE 5 "
	        + " END AS SMALLINT) AS COLUMN_TYPE, "
	        + " CAST(CASE pg_catalog.format_type(p.prorettype, NULL) "
	        + " WHEN 'text' THEN 12 "
	        + " WHEN 'bit' THEN  -7 "
	        + " WHEN 'bool' THEN  -7 "
	        + " WHEN 'boolean' THEN  -7 "
	        + " WHEN 'varchar' THEN 12 "
	        + " WHEN 'character varying' THEN  12 "
	        + " WHEN '\"char\"' THEN 1"
	        + " WHEN 'char' THEN  1 "
	        + " WHEN 'character' THEN  1 "
	        + " WHEN 'nchar' THEN 1 "
	        + " WHEN 'bpchar' THEN 1 "
	        + " WHEN 'nvarchar' THEN 12 "
	        + " WHEN 'date' THEN 91 "
	        + " WHEN 'timestamp' THEN 93 "
	        + " WHEN 'timestamp without time zone' THEN 93 "
	        + " WHEN 'timestamptz' THEN 2014 "
	        + " WHEN 'timestamp with time zone' THEN 2014 "
	        + " WHEN 'smallint' THEN 5 "
	        + " WHEN 'int2' THEN 5 "
	        + " WHEN 'integer' THEN 4 "
	        + " WHEN 'int' THEN 4 "
	        + " WHEN 'int4' THEN 4 "
	        + " WHEN 'bigint' THEN -5 "
	        + " WHEN 'int8' THEN -5 "
	        + " WHEN 'real' THEN 7 "
	        + " WHEN 'float4' THEN 7 "
	        + " WHEN 'double precision' THEN 6 "
	        + " WHEN 'float8' THEN 6 "
	        + " WHEN 'float' THEN 6 "
	        + " WHEN 'decimal' THEN 3 "
	        + " WHEN 'numeric' THEN 2 "
	        + " WHEN '_float4' THEN 2003 "
	        + " WHEN '_aclitem' THEN 2003 "
	        + " WHEN '_text' THEN 2003 "
	        + " WHEN 'bytea' THEN -2 "
	        + " WHEN 'oid' THEN -5 "
	        + " WHEN 'name' THEN 12 "
	        + " WHEN '_int4' THEN 2003 "
	        + " WHEN '_int2' THEN 2003 "
	        + " WHEN 'ARRAY' THEN 2003 "
	        + " WHEN 'geometry' THEN -4 "
	        + " WHEN 'super' THEN -1 "
	        + " WHEN 'varbyte' THEN -4 "
	        + " ELSE 1111 "
	        + " END AS SMALLINT) AS DATA_TYPE, "
	        + " pg_catalog.format_type(p.prorettype, NULL) AS TYPE_NAME, "
	        + " CASE pg_catalog.format_type(p.prorettype, NULL) "
	        + " WHEN 'text' THEN NULL "
	        + " WHEN 'varchar' THEN NULL "
	        + " WHEN 'character varying' THEN NULL "
	        + " WHEN '\"char\"' THEN NULL "
	        + " WHEN 'character' THEN NULL "
	        + " WHEN 'nchar' THEN NULL "
	        + " WHEN 'bpchar' THEN NULL "
	        + " WHEN 'nvarchar' THEN NULL "
	        + " WHEN 'text' THEN NULL "
	        + " WHEN 'date' THEN NULL "
	        + " WHEN 'timestamp' THEN 6 "
	        + " WHEN 'smallint' THEN 5 "
	        + " WHEN 'int2' THEN 5 "
	        + " WHEN 'integer' THEN 10 "
	        + " WHEN 'int' THEN 10 "
	        + " WHEN 'int4' THEN 10 "
	        + " WHEN 'bigint' THEN 19 "
	        + " WHEN 'int8' THEN 19 "
	        + " WHEN 'decimal' THEN 38 "
	        + " WHEN 'real' THEN 24 "
	        + " WHEN 'float4' THEN 53 "
	        + " WHEN 'double precision' THEN 53 "
	        + " WHEN 'float8' THEN 53 "
	        + " WHEN 'float' THEN 53 "
	        + " WHEN 'geometry' THEN NULL "
	        + " WHEN 'super' THEN " + superMaxLength
	        + " WHEN 'varbyte' THEN " + varbyteMaxLength
	        + " ELSE " + unknownColumnSize
	        + " END AS COLUMN_SIZE, "
	        + " CASE pg_catalog.format_type(p.prorettype, NULL) "
	        + " WHEN 'text' THEN NULL "
	        + " WHEN 'varchar' THEN NULL "
	        + " WHEN 'character varying' THEN NULL "
	        + " WHEN '\"char\"' THEN NULL "
	        + " WHEN 'character' THEN NULL "
	        + " WHEN 'nchar' THEN NULL "
	        + " WHEN 'bpchar' THEN NULL "
	        + " WHEN 'nvarchar' THEN NULL "
	        + " WHEN 'date' THEN 6 "
	        + " WHEN 'timestamp' THEN 6 "
	        + " WHEN 'smallint' THEN 2 "
	        + " WHEN 'int2' THEN 2 "
	        + " WHEN 'integer' THEN 4 "
	        + " WHEN 'int' THEN 4 "
	        + " WHEN 'int4' THEN 4 "
	        + " WHEN 'bigint' THEN 20 "
	        + " WHEN 'int8' THEN 20 "
	        + " WHEN 'decimal' THEN 8 "
	        + " WHEN 'real' THEN 4 "
	        + " WHEN 'float4' THEN 8 "
	        + " WHEN 'double precision' THEN 8 "
	        + " WHEN 'float8' THEN 8 "
	        + " WHEN 'float' THEN  8 "
	        + " WHEN 'geometry' THEN NULL "
	        + " WHEN 'super' THEN " + superMaxLength
	        + " WHEN 'varbyte' THEN " + varbyteMaxLength
	        + " END AS LENGTH, "
	        + " CAST(CASE pg_catalog.format_type(p.prorettype, NULL) "
	        + " WHEN 'smallint' THEN 0 "
	        + " WHEN 'int2' THEN 0 "
	        + " WHEN 'integer' THEN 0 "
	        + " WHEN 'int' THEN 0 "
	        + " WHEN 'int4' THEN 0 "
	        + " WHEN 'bigint' THEN 0 "
	        + " WHEN 'int8' THEN 0 "
	        + " WHEN 'decimal' THEN 0 "
	        + " WHEN 'real' THEN 8 "
	        + " WHEN 'float4' THEN 8 "
	        + " WHEN 'double precision' THEN 17 "
	        + " WHEN 'float' THEN 17 "
	        + " WHEN 'float8' THEN 17 "
	        + " WHEN 'numeric' THEN 0 "
	        + " WHEN 'timestamp' THEN 6 "
	        + " WHEN 'timestamp without time zone' THEN 6 "
	        + " WHEN 'timestamptz' THEN 6 "
	        + " WHEN 'timestamp with time zone' THEN 6 "
	        + " ELSE NULL END AS SMALLINT) AS DECIMAL_DIGITS, "
	        + " 10 AS NUM_PREC_RADIX, "
	        + " CAST(2 AS SMALLINT) AS NULLABLE, "
	        + " CAST('' AS VARCHAR(256)) AS REMARKS, "
	        + " CAST(NULL AS SMALLINT) AS CHAR_OCTET_LENGTH, "
	        + " CAST(0 AS SMALLINT) AS ORDINAL_POSITION, "
	        + " CAST('' AS VARCHAR(256)) AS IS_NULLABLE, "
	        + " p.proname || '_' || p.prooid AS SPECIFIC_NAME, "
	        + " p.prooid as PROOID, "
	        + " -1 AS PROARGINDEX "
	
	        + " FROM pg_catalog.pg_proc_info p LEFT JOIN pg_namespace n ON n.oid = p.pronamespace "
	        + " WHERE pg_catalog.format_type(p.prorettype, NULL) != 'void' "
	        + " AND prokind = 'f' ");
    
		functionColumnQuery.append(getCatalogFilterCondition(catalog));
	
    if (schemaPattern != null && !schemaPattern.isEmpty()) {
//      sql += " AND n.nspname LIKE " + escapeQuotes(schemaPattern);
    	functionColumnQuery.append(" AND n.nspname LIKE " + escapeQuotes(schemaPattern));
    }
    if (functionNamePattern != null && !functionNamePattern.isEmpty()) {
//      sql += " AND p.proname LIKE " + escapeQuotes(functionNamePattern);
    	functionColumnQuery.append(" AND p.proname LIKE " + escapeQuotes(functionNamePattern));    	
    }
    if (columnNamePattern != null && !columnNamePattern.isEmpty()) {
    	functionColumnQuery.append(" AND COLUMN_NAME LIKE " + escapeQuotes(columnNamePattern));    	
    }
    
    functionColumnQuery.append(" UNION ALL ");

    functionColumnQuery.append(" SELECT DISTINCT current_database() AS PROCEDURE_CAT, "
            + " PROCEDURE_SCHEM, "
            + " PROCEDURE_NAME, "
            + "CAST(CASE (char_length(COLUMN_NAME) > 0) WHEN 't' THEN COLUMN_NAME "
            + "ELSE '' "
            + "END AS VARCHAR(256)) AS COLUMN_NAME, "

            + " CAST( CASE COLUMN_TYPE "
            + " WHEN 105 THEN 1 "
            + " WHEN 98 THEN 2 "
            + " WHEN 111 THEN 4 "
            + " ELSE 5 END AS SMALLINT) AS COLUMN_TYPE, "
            + " CAST(CASE DATA_TYPE "
            + " WHEN 'text' THEN 12 "
            + " WHEN 'bit' THEN  -7 "
            + " WHEN 'bool' THEN  -7 "
            + " WHEN 'boolean' THEN  -7 "
            + " WHEN 'varchar' THEN 12 "
            + " WHEN 'character varying' THEN  12 "
            + " WHEN '\"char\"' THEN  1 "
            + " WHEN 'char' THEN  1 "
            + " WHEN 'character' THEN  1 "
            + " WHEN 'nchar' THEN 1 "
            + " WHEN 'bpchar' THEN 1 "
            + " WHEN 'nvarchar' THEN 12 "
            + " WHEN 'date' THEN 91 "
            + " WHEN 'timestamp' THEN 93 "
            + " WHEN 'timestamp without time zone' THEN 93 "
            + " WHEN 'timestamptz' THEN 2014 "
            + " WHEN 'timestamp with time zone' THEN 2014 "
            + " WHEN 'smallint' THEN 5 "
            + " WHEN 'int2' THEN 5 "
            + " WHEN 'integer' THEN 4 "
            + " WHEN 'int' THEN 4 "
            + " WHEN 'int4' THEN 4 "
            + " WHEN 'bigint' THEN -5 "
            + " WHEN 'int8' THEN -5 "
            + " WHEN 'real' THEN 7 "
            + " WHEN 'float4' THEN 7 "
            + " WHEN 'double precision' THEN 6 "
            + " WHEN 'float8' THEN 6 "
            + " WHEN 'float' THEN 6 "
            + " WHEN 'decimal' THEN 3 "
            + " WHEN 'numeric' THEN 2 "
            + " WHEN 'bytea' THEN -2 "
            + " WHEN 'oid' THEN -5 "
            + " WHEN 'name' THEN 12 "
            + " WHEN 'ARRAY' THEN 2003 "
            + " WHEN 'geometry' THEN -4 "
            + " WHEN 'super' THEN -1 "
            + " WHEN 'varbyte' THEN -4 "
            + " ELSE 1111 "
            + " END AS SMALLINT) AS DATA_TYPE, "
            + " TYPE_NAME, "
            + " CASE COLUMN_SIZE "
            + " WHEN 'text' THEN NULL "
            + " WHEN 'varchar' THEN NULL "
            + " WHEN 'character varying' THEN NULL "
            + " WHEN '\"char\"' THEN NULL "
            + " WHEN 'character' THEN NULL "
            + " WHEN 'nchar' THEN NULL "
            + " WHEN 'bpchar' THEN NULL "
            + " WHEN 'nvarchar' THEN NULL "
            + " WHEN 'text' THEN NULL "
            + " WHEN 'date' THEN NULL "
            + " WHEN 'timestamp' THEN 6 "
            + " WHEN 'smallint' THEN 5 "
            + " WHEN 'int2' THEN 5 "
            + " WHEN 'integer' THEN 10 "
            + " WHEN 'int' THEN 10 "
            + " WHEN 'int4' THEN 10 "
            + " WHEN 'bigint' THEN 19 "
            + " WHEN 'int8' THEN 19 "
            + " WHEN 'decimal' THEN 38 "
            + " WHEN 'real' THEN 24 "
            + " WHEN 'float4' THEN 53 "
            + " WHEN 'double precision' THEN 53 "
            + " WHEN 'float8' THEN 53 "
            + " WHEN 'float' THEN 53 "
            + " WHEN 'geometry' THEN NULL "
            + " WHEN 'super' THEN " + superMaxLength
            + " WHEN 'varbyte' THEN " + varbyteMaxLength
            + " ELSE " + unknownColumnSize
            + " END AS COLUMN_SIZE, "
            + " CASE LENGTH "
            + " WHEN 'text' THEN NULL "
            + " WHEN 'varchar' THEN NULL "
            + " WHEN 'character varying' THEN NULL "
            + " WHEN '\"char\"' THEN NULL "
            + " WHEN 'character' THEN NULL "
            + " WHEN 'nchar' THEN NULL "
            + " WHEN 'bpchar' THEN NULL "
            + " WHEN 'nvarchar' THEN NULL "
            + " WHEN 'date' THEN 6 "
            + " WHEN 'timestamp' THEN 6 "
            + " WHEN 'smallint' THEN 2 "
            + " WHEN 'int2' THEN 2 "
            + " WHEN 'integer' THEN 4 "
            + " WHEN 'int' THEN 4 "
            + " WHEN 'int4' THEN 4 "
            + " WHEN 'bigint' THEN 20 "
            + " WHEN 'int8' THEN 20 "
            + " WHEN 'decimal' THEN 8 "
            + " WHEN 'real' THEN 4 "
            + " WHEN 'float4' THEN 8 "
            + " WHEN 'double precision' THEN 8 "
            + " WHEN 'float8' THEN 8 "
            + " WHEN 'float' THEN  8 "
            + " WHEN 'geometry' THEN NULL "
            + " WHEN 'super' THEN " + superMaxLength
            + " WHEN 'varbyte' THEN " + varbyteMaxLength
            + " END AS LENGTH, "
            + " CAST(CASE DECIMAL_DIGITS "
            + " WHEN 'smallint' THEN 0 "
            + " WHEN 'int2' THEN 0 "
            + " WHEN 'integer' THEN 0 "
            + " WHEN 'int' THEN 0 "
            + " WHEN 'int4' THEN 0 "
            + " WHEN 'bigint' THEN 0 "
            + " WHEN 'int8' THEN 0 "
            + " WHEN 'decimal' THEN 0 "
            + " WHEN 'real' THEN 8 "
            + " WHEN 'float4' THEN 8 "
            + " WHEN 'double precision' THEN 17 "
            + " WHEN 'float' THEN 17 "
            + " WHEN 'float8' THEN 17 "
            + " WHEN 'numeric' THEN 0 "
            + " WHEN 'timestamp' THEN 6 "
            + " WHEN 'timestamp without time zone' THEN 6 "
            + " WHEN 'timestamptz' THEN 6 "
            + " WHEN 'timestamp with time zone' THEN 6 "
            + " ELSE NULL END AS SMALLINT) AS DECIMAL_DIGITS, "
            + " 10 AS NUM_PREC_RADIX, "
            + " CAST(2 AS SMALLINT) AS NULLABLE, "
            + " CAST(''AS VARCHAR(256)) AS REMARKS, "
            + " CAST(NULL AS SMALLINT) AS CHAR_OCTET_LENGTH, "
            + " PROARGINDEX AS ORDINAL_POSITION, "
            + " CAST(''AS VARCHAR(256)) AS IS_NULLABLE, "
            + " SPECIFIC_NAME, PROOID, PROARGINDEX "
            + " FROM ( "
            + " SELECT current_database() AS PROCEDURE_CAT,"
            + " n.nspname AS PROCEDURE_SCHEM, "
            + " proname AS PROCEDURE_NAME, "
            + " CASE WHEN (proallargtypes is NULL) THEN proargnames[pos+1] "
            + " ELSE proargnames[pos] END AS COLUMN_NAME,"
            + " CASE WHEN proargmodes is NULL THEN 105 "
            + " ELSE CAST(proargmodes[pos] AS INT) END AS COLUMN_TYPE, "
            + " CASE WHEN proallargtypes is NULL THEN pg_catalog.format_type(proargtypes[pos], NULL)"
            + " ELSE pg_catalog.format_type(proallargtypes[pos], NULL) END AS DATA_TYPE,"
            + " CASE WHEN proallargtypes is NULL THEN pg_catalog.format_type(proargtypes[pos], NULL) "
            + " ELSE pg_catalog.format_type(proallargtypes[pos], NULL) END AS TYPE_NAME,"
            + " CASE WHEN proallargtypes is NULL THEN pg_catalog.format_type(proargtypes[pos], NULL)"
            + " ELSE pg_catalog.format_type(proallargtypes[pos], NULL) END AS COLUMN_SIZE,"
            + " CASE WHEN proallargtypes is NULL THEN pg_catalog.format_type(proargtypes[pos], NULL)"
            + " ELSE pg_catalog.format_type(proallargtypes[pos], NULL) END AS LENGTH,"
            + " CASE WHEN proallargtypes is NULL THEN pg_catalog.format_type(proargtypes[pos], NULL)"
            + " ELSE pg_catalog.format_type(proallargtypes[pos], NULL) END AS DECIMAL_DIGITS,"
            + " CASE WHEN proallargtypes is NULL THEN pg_catalog.format_type(proargtypes[pos], NULL)"
            + " ELSE pg_catalog.format_type(proallargtypes[pos], NULL) END AS RADIX,"
            + " CAST(2 AS SMALLINT) AS NULLABLE,"
            + " CAST(''AS VARCHAR(256)) AS REMARKS,"
            + " pg_catalog.format_type(proargtypes[pos], NULL) AS CHAR_OCTET_LENGTH,"
            + " CASE WHEN (proallargtypes is NULL) THEN pos+1"
            + " WHEN pos = array_upper(proallargtypes, 1) THEN 0"
            + " ELSE pos END AS ORDINAL_POSITION,"
            + " CAST('' AS VARCHAR(256)) AS IS_NULLABLE,"
            + " p.prooid AS PROOID,"
            + " CASE WHEN (proallargtypes is NULL) THEN pos+1"
            + " WHEN prokind = 'f' AND pos = array_upper(proallargtypes, 1) THEN 0"
            + " ELSE pos END AS PROARGINDEX, "
            + " p.proname || '_' || p.prooid AS SPECIFIC_NAME "
            + " FROM (pg_catalog.pg_proc_info p LEFT JOIN pg_namespace n"
            + " ON n.oid = p.pronamespace)"
            + " LEFT JOIN (SELECT "
            + " CASE WHEN (proallargtypes IS NULL) "
            + " THEN generate_series(array_lower(proargnames, 1), array_upper(proargnames, 1))-1"
            + " ELSE generate_series(array_lower(proargnames, 1), array_upper(proargnames, 1)+1)-1 "
            + " END AS pos"
            + " FROM pg_catalog.pg_proc_info p ) AS s ON (pos >= 0 AND pos <= pronargs+1)"
            + " WHERE prokind = 'f' ");
    
    if (schemaPattern != null && !schemaPattern.isEmpty()) {
    	functionColumnQuery.append(" AND n.nspname LIKE " + escapeQuotes(schemaPattern));
    }
    if (functionNamePattern != null && !functionNamePattern.isEmpty()) {
    	functionColumnQuery.append(" AND p.proname LIKE " + escapeQuotes(functionNamePattern));    	
    }
	  if (columnNamePattern != null && !columnNamePattern.isEmpty()) {
	  	functionColumnQuery.append(" AND COLUMN_NAME LIKE " + escapeQuotes(columnNamePattern));    	
	  }
    
    functionColumnQuery.append(" ) AS INPUT_PARAM_TABLE"
        + " WHERE ORDINAL_POSITION IS NOT NULL"
        + " ) AS RESULT_SET WHERE (DATA_TYPE != 1111 OR (TYPE_NAME IS NOT NULL AND TYPE_NAME != '-'))"
        + " ORDER BY PROCEDURE_CAT ,PROCEDURE_SCHEM,"
        + " PROCEDURE_NAME, PROOID, PROARGINDEX, COLUMN_TYPE DESC");
	  
//    sql += " ORDER BY n.nspname, p.proname, p.prooid::text ";

//    byte[] isnullableUnknown = new byte[0];

//    Statement stmt = connection.createStatement();
//    ResultSet rs = stmt.executeQuery(functionColumnQuery.toString()); // sql
    
/*    
    while (rs.next()) {
      byte[] schema = rs.getBytes("nspname");
      byte[] functionName = rs.getBytes("proname");
      byte[] specificName =
          connection.encodeString(rs.getString("proname") + "_" + rs.getString("prooid"));
      int returnType = (int) rs.getLong("prorettype");
      String returnTypeType = rs.getString("typtype");
      int returnTypeRelid = (int) rs.getLong("typrelid");

      String strArgTypes = rs.getString("proargtypes");
      StringTokenizer st = new StringTokenizer(strArgTypes);
      List<Long> argTypes = new ArrayList<Long>();
      while (st.hasMoreTokens()) {
        argTypes.add(Long.valueOf(st.nextToken()));
      }

      String[] argNames = null;
      Array argNamesArray = rs.getArray("proargnames");
      if (argNamesArray != null) {
        argNames = (String[]) argNamesArray.getArray();
      }

      String[] argModes = null;
      Array argModesArray = rs.getArray("proargmodes");
      if (argModesArray != null) {
        argModes = (String[]) argModesArray.getArray();
      }

      int numArgs = argTypes.size();

      Long[] allArgTypes = null;
      Array allArgTypesArray = rs.getArray("proallargtypes");
      if (allArgTypesArray != null) {
        allArgTypes = (Long[]) allArgTypesArray.getArray();
        numArgs = allArgTypes.length;
      }

      // decide if we are returning a single column result.
      if (returnTypeType.equals("b") || returnTypeType.equals("d") || returnTypeType.equals("e")
          || (returnTypeType.equals("p") && argModesArray == null)) {
        byte[][] tuple = new byte[columns][];
        tuple[0] = connection.encodeString(connection.getCatalog());
        tuple[1] = schema;
        tuple[2] = functionName;
        tuple[3] = connection.encodeString("returnValue");
        tuple[4] = connection
            .encodeString(Integer.toString(java.sql.DatabaseMetaData.functionReturn));
        tuple[5] = connection
            .encodeString(Integer.toString(connection.getTypeInfo().getSQLType(returnType)));
        tuple[6] = connection.encodeString(connection.getTypeInfo().getRSType(returnType));
        tuple[7] = null;
        tuple[8] = null;
        tuple[9] = null;
        tuple[10] = null;
        tuple[11] = connection
            .encodeString(Integer.toString(java.sql.DatabaseMetaData.functionNullableUnknown));
        tuple[12] = null;
        tuple[14] = connection.encodeString(Integer.toString(0));
        tuple[15] = isnullableUnknown;
        tuple[16] = specificName;

        v.add(new Tuple(tuple));
      }

      // Add a row for each argument.
      for (int i = 0; i < numArgs; i++) {
        byte[][] tuple = new byte[columns][];
        tuple[0] = connection.encodeString(connection.getCatalog());
        tuple[1] = schema;
        tuple[2] = functionName;

        if (argNames != null) {
          tuple[3] = connection.encodeString(argNames[i]);
        } else {
          tuple[3] = connection.encodeString("$" + (i + 1));
        }

        int columnMode = DatabaseMetaData.functionColumnIn;
        if (argModes != null && argModes[i] != null) {
          if (argModes[i].equals("o")) {
            columnMode = DatabaseMetaData.functionColumnOut;
          } else if (argModes[i].equals("b")) {
            columnMode = DatabaseMetaData.functionColumnInOut;
          } else if (argModes[i].equals("t")) {
            columnMode = DatabaseMetaData.functionReturn;
          }
        }

        tuple[4] = connection.encodeString(Integer.toString(columnMode));

        int argOid;
        if (allArgTypes != null) {
          argOid = allArgTypes[i].intValue();
        } else {
          argOid = argTypes.get(i).intValue();
        }

        tuple[5] =
            connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(argOid)));
        tuple[6] = connection.encodeString(connection.getTypeInfo().getRSType(argOid));
        tuple[7] = null;
        tuple[8] = null;
        tuple[9] = null;
        tuple[10] = null;
        tuple[11] =
            connection.encodeString(Integer.toString(DatabaseMetaData.functionNullableUnknown));
        tuple[12] = null;
        tuple[14] = connection.encodeString(Integer.toString(i + 1));
        tuple[15] = isnullableUnknown;
        tuple[16] = specificName;

        v.add(new Tuple(tuple));
      }

      // if we are returning a multi-column result.
      if (returnTypeType.equals("c") || (returnTypeType.equals("p") && argModesArray != null)) {
        String columnsql = "SELECT a.attname,a.atttypid FROM pg_catalog.pg_attribute a "
            + " WHERE a.attrelid = " + returnTypeRelid
            + " AND NOT a.attisdropped AND a.attnum > 0 ORDER BY a.attnum ";
        Statement columnstmt = connection.createStatement();
        ResultSet columnrs = columnstmt.executeQuery(columnsql);
        while (columnrs.next()) {
          int columnTypeOid = (int) columnrs.getLong("atttypid");
          byte[][] tuple = new byte[columns][];
          tuple[0] = connection.encodeString(connection.getCatalog());
          tuple[1] = schema;
          tuple[2] = functionName;
          tuple[3] = columnrs.getBytes("attname");
          tuple[4] = connection
              .encodeString(Integer.toString(java.sql.DatabaseMetaData.functionColumnResult));
          tuple[5] = connection
              .encodeString(Integer.toString(connection.getTypeInfo().getSQLType(columnTypeOid)));
          tuple[6] = connection.encodeString(connection.getTypeInfo().getRSType(columnTypeOid));
          tuple[7] = null;
          tuple[8] = null;
          tuple[9] = null;
          tuple[10] = null;
          tuple[11] = connection
              .encodeString(Integer.toString(java.sql.DatabaseMetaData.functionNullableUnknown));
          tuple[12] = null;
          tuple[14] = connection.encodeString(Integer.toString(0));
          tuple[15] = isnullableUnknown;
          tuple[16] = specificName;

          v.add(new Tuple(tuple));
        }
        columnrs.close();
        columnstmt.close();
      }
    }
*/    
//    rs.close();
//    stmt.close();

//    ResultSet rc = ((BaseStatement) createMetaDataStatement()).createDriverResultSet(f, v);
    	ResultSet rc = createMetaDataStatement().executeQuery(functionColumnQuery.toString());
    
    if (RedshiftLogger.isEnable())
    	connection.getLogger().logFunction(false, rc);
    
    return rc;
  }