/** * Generate the columns portion of the table creation SQL. * * <p>Assumes {@link #fetchSrcColumnTypeList() } has already been executed. * * @return the columns portion of the table creation SQL. * @throws SQLException */ protected String generateColumnSQL() throws SQLException { StringBuilder sb = new StringBuilder(); ResultSetMetaData rsmd = getResultSetMetaData(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { // columns are one's-based if (i != 1) { sb.append(", "); } sb.append(rsmd.getColumnName(i).replace('#', '_')).append(" "); switch (getDestDb().getDbType()) { case AS400: sb.append( getSrcColumnTypeList().getColumnSQLType(i - 1)); // but this list is zeroes-based! break; case PGSQL: String pgDataTypeName = getSrcColumnTypeList() .getColumnPostgresqlType(i - 1); // but this list is zeroes-based! if (pgDataTypeName.equals("integer") && rsmd.getPrecision(i) > 0) { pgDataTypeName = "bigint"; } sb.append(pgDataTypeName); break; case MSSQL: sb.append( getSrcColumnTypeList().getColumnSQLType(i - 1)); // but this list is zeroes-based! } // if (getDestDb().getDbType() != Db.DBTYPE.PGSQL) { int preciz = rsmd.getPrecision(i); if (preciz > 0) { // If Postgres, append any precision>0 UNLESS type is among the following // This list is not complete. Probably should be turned around to // only append precision for small set of types like character and numeric // which accept precision. if (getDestDb().getDbType() == Db.DBTYPE.PGSQL) { String pgDataTypeName = getSrcColumnTypeList().getColumnPostgresqlType(i - 1); switch (pgDataTypeName) { case "integer": // no precision for this datatype in Postgres break; case "bigint": // no precision for this datatype in Postgres break; case "smallint": // no precision for this datatype in Postgres break; case "text": // no precision for this datatype in Postgres break; case "bytea": // no precision for this datatype in Postgres break; default: // other types get precision sb.append("(").append(preciz).append(")"); } } else { // For databases other than Postgres, always append precision if non-zero // At least, we think that's how it works, until we have tested more!!! sb.append("(").append(preciz).append(")"); } } if (Db.isNumeric(rsmd.getColumnType(i))) { if (!rsmd.isSigned(i)) { sb.append(" UNSIGNED"); } } if (rsmd.isNullable(i) == ResultSetMetaData.columnNoNulls) { sb.append(" NOT NULL"); } else { sb.append(" NULL"); } if (rsmd.isAutoIncrement(i)) { sb.append(" auto_increment"); } } ResultSet pk = getDatabaseMetaData().getPrimaryKeys(null, null, getTableName()); boolean first = true; while (pk.next()) { { if (first) { first = false; sb.append(", "); sb.append("PRIMARY KEY("); } else { sb.append(" , "); } sb.append(pk.getString("COLUMN_NAME")); } } if (!first) { // if not-first then we replicated a primary key sb.append(')'); } else { // otherwise, we have to generate one sb.append(", ").append(generatePrimaryKey()); } return sb.toString(); }