/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.test.synth.sql; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; /** * A column of a table. */ class Column { private static final int[] TYPES = { Types.INTEGER, Types.VARCHAR, Types.DECIMAL, Types.DATE, Types.TIME, Types.TIMESTAMP, Types.BOOLEAN, Types.BINARY, Types.VARBINARY, Types.CLOB, Types.BLOB, Types.DOUBLE, Types.BIGINT, Types.TIMESTAMP, Types.BIT, }; private TestSynth config; private String name; private int type; private int precision; private int scale; private boolean isNullable; private boolean isPrimaryKey; // TODO test isAutoincrement; private Column(TestSynth config) { this.config = config; } Column(ResultSetMetaData meta, int index) throws SQLException { name = meta.getColumnLabel(index); type = meta.getColumnType(index); switch (type) { case Types.DECIMAL: precision = meta.getPrecision(index); scale = meta.getScale(index); break; case Types.BLOB: case Types.BINARY: case Types.VARBINARY: case Types.CLOB: case Types.LONGVARCHAR: case Types.DATE: case Types.TIME: case Types.INTEGER: case Types.VARCHAR: case Types.CHAR: case Types.BIGINT: case Types.NUMERIC: case Types.TIMESTAMP: case Types.NULL: case Types.LONGVARBINARY: case Types.DOUBLE: case Types.REAL: case Types.OTHER: case Types.BIT: case Types.BOOLEAN: break; default: throw new AssertionError("type=" + type); } } /** * Check if this data type supports comparisons for this database. * * @param config the configuration * @param type the SQL type * @return true if the value can be used in conditions */ static boolean isConditionType(TestSynth config, int type) { switch (config.getMode()) { case TestSynth.H2: case TestSynth.H2_MEM: return true; case TestSynth.MYSQL: case TestSynth.HSQLDB: case TestSynth.POSTGRESQL: switch (type) { case Types.INTEGER: case Types.VARCHAR: case Types.DECIMAL: case Types.DATE: case Types.TIME: case Types.TIMESTAMP: case Types.DOUBLE: case Types.BIGINT: case Types.BOOLEAN: case Types.BIT: return true; case Types.BINARY: case Types.VARBINARY: case Types.BLOB: case Types.CLOB: case Types.LONGVARCHAR: case Types.LONGVARBINARY: return false; default: throw new AssertionError("type=" + type); } default: throw new AssertionError("type=" + type); } } private String getTypeName() { switch (type) { case Types.INTEGER: return "INT"; case Types.VARCHAR: return "VARCHAR(" + precision + ")"; case Types.DECIMAL: return "NUMERIC(" + precision + ", " + scale + ")"; case Types.DATE: return "DATE"; case Types.TIME: return "TIME"; case Types.TIMESTAMP: return "TIMESTAMP"; case Types.BINARY: case Types.VARBINARY: if (config.is(TestSynth.POSTGRESQL)) { return "BYTEA"; } return "BINARY(" + precision + ")"; case Types.CLOB: { if (config.is(TestSynth.HSQLDB)) { return "LONGVARCHAR"; } else if (config.is(TestSynth.POSTGRESQL)) { return "TEXT"; } return "CLOB"; } case Types.BLOB: { if (config.is(TestSynth.HSQLDB)) { return "LONGVARBINARY"; } return "BLOB"; } case Types.DOUBLE: if (config.is(TestSynth.POSTGRESQL)) { return "DOUBLE PRECISION"; } return "DOUBLE"; case Types.BIGINT: return "BIGINT"; case Types.BOOLEAN: case Types.BIT: return "BOOLEAN"; default: throw new AssertionError("type=" + type); } } String getCreateSQL() { String sql = name + " " + getTypeName(); if (!isNullable) { sql += " NOT NULL"; } return sql; } String getName() { return name; } Value getRandomValue() { return Value.getRandom(config, type, precision, scale, isNullable); } // Value getRandomValueNotNull() { // return Value.getRandom(config, type, precision, scale, false); // } /** * Generate a random column. * * @param config the configuration * @return the column */ static Column getRandomColumn(TestSynth config) { Column column = new Column(config); column.name = "C_" + config.randomIdentifier(); int randomType; while (true) { randomType = TYPES[config.random().getLog(TYPES.length)]; if (config.is(TestSynth.POSTGRESQL) && (randomType == Types.BINARY || randomType == Types.VARBINARY || randomType == Types.BLOB)) { continue; } break; } column.type = randomType; column.precision = config.random().getInt(20) + 2; column.scale = config.random().getInt(column.precision); column.isNullable = config.random().getBoolean(50); return column; } boolean getPrimaryKey() { return isPrimaryKey; } void setPrimaryKey(boolean b) { isPrimaryKey = b; } void setNullable(boolean b) { isNullable = b; } /** * The the column type. * * @return the type */ int getType() { return type; } }