diff --git a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTable.java b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTable.java index 4691ec84d70923582e3e0d3157cdb45452218a51..a78007aa8d7d68045597fd1c93711fa3542dcc45 100644 --- a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTable.java +++ b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTable.java @@ -26,16 +26,23 @@ import org.jkiss.dbeaver.ext.exasol.editors.ExasolSourceObject; import org.jkiss.dbeaver.ext.exasol.tools.ExasolUtils; import org.jkiss.dbeaver.model.DBPNamedObject2; import org.jkiss.dbeaver.model.DBPRefreshableObject; +import org.jkiss.dbeaver.model.DBUtils; +import org.jkiss.dbeaver.model.exec.DBCException; +import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement; +import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet; +import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCStructCache; import org.jkiss.dbeaver.model.meta.Association; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor; import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.DBSObjectState; import org.jkiss.dbeaver.model.struct.rdb.DBSTableForeignKey; import java.sql.ResultSet; +import java.sql.SQLException; import java.sql.Timestamp; import java.util.Collection; @@ -46,65 +53,154 @@ public class ExasolTable extends ExasolTableBase implements DBPRefreshableObject private Boolean hasDistKey; private Timestamp lastCommit; - private long sizeRaw; - private long sizeCompressed; - private float deletePercentage; - private Timestamp createTime; + private Boolean hasRead; + private static String readAdditionalInfo = "select * from (" + + "select" + + " table_schema," + + " table_name," + + " table_owner," + + " table_has_distribution_key," + + " table_comment," + + " delete_percentage," + + " o.created," + + " o.last_commit," + + " s.raw_object_size," + + " s.mem_object_size," + + " s.object_type" + + " from" + + " EXA_ALL_OBJECTS o" + + " inner join" + + " EXA_ALL_TABLES T" + + " on" + + " o.root_name = t.table_schema and" + + " t.table_name = o.object_name and" + + " o.object_type = 'TABLE'" + + " inner join " + + " EXA_ALL_OBJECT_SIZES s" + + " on" + + " o.root_name = s.root_name and" + + " o.object_name = s.object_name and" + + " o.object_type = s.object_type" + + " where o.root_name = ? and o.object_name = ? and t.table_schema = ? and t.table_name = ?" + + " union all " + + " select schema_name as table_schema," + + " object_name as table_name," + + " 'SYS' as table_owner," + + " false as table_has_distribution_key," + + " object_comment as table_comment," + + " 0 as delete_percentage," + + " cast( null as timestamp) as created," + + " cast( null as timestamp) as last_commit," + + " 0 as raw_object_size," + + " 0 as mem_object_size," + + " object_type" + + " from SYS.EXA_SYSCAT WHERE object_type = 'TABLE' and schema_name = ? and object_name = ?" + + ") as o" + + " order by table_schema,o.table_name"; + + public ExasolTable(DBRProgressMonitor monitor, ExasolSchema schema, ResultSet dbResult) { super(monitor, schema, dbResult); - this.hasDistKey = JDBCUtils.safeGetBoolean(dbResult, "TABLE_HAS_DISTRIBUTION_KEY"); - this.lastCommit = JDBCUtils.safeGetTimestamp(dbResult, "LAST_COMMIT"); - this.sizeRaw = JDBCUtils.safeGetLong(dbResult, "RAW_OBJECT_SIZE"); - this.sizeCompressed = JDBCUtils.safeGetLong(dbResult, "MEM_OBJECT_SIZE"); - this.deletePercentage = JDBCUtils.safeGetFloat(dbResult, "DELETE_PERCENTAGE"); - this.createTime = JDBCUtils.safeGetTimestamp(dbResult, "CREATED"); + hasRead=false; } public ExasolTable(ExasolSchema schema, String name) { super(schema, name, false); + hasRead=false; } - + private void read() throws DBCException + { + JDBCSession session = DBUtils.openMetaSession(VoidProgressMonitor.INSTANCE, getDataSource(), "Read Table Details"); + try (JDBCPreparedStatement stmt = session.prepareStatement(readAdditionalInfo)) + { + stmt.setString(1, this.getSchema().getName()); + stmt.setString(2, this.getName()); + stmt.setString(3, this.getSchema().getName()); + stmt.setString(4, this.getName()); + stmt.setString(5, this.getSchema().getName()); + stmt.setString(6, this.getName()); + + try (JDBCResultSet dbResult = stmt.executeQuery()) + { + dbResult.next(); + this.hasDistKey = JDBCUtils.safeGetBoolean(dbResult, "TABLE_HAS_DISTRIBUTION_KEY"); + this.lastCommit = JDBCUtils.safeGetTimestamp(dbResult, "LAST_COMMIT"); + this.sizeRaw = JDBCUtils.safeGetLong(dbResult, "RAW_OBJECT_SIZE"); + this.sizeCompressed = JDBCUtils.safeGetLong(dbResult, "MEM_OBJECT_SIZE"); + this.deletePercentage = JDBCUtils.safeGetFloat(dbResult, "DELETE_PERCENTAGE"); + this.createTime = JDBCUtils.safeGetTimestamp(dbResult, "CREATED"); + this.hasRead = true; + } + + } catch (SQLException e) { + throw new DBCException(e,getDataSource()); + } + + + + + } + + @Override + public void refreshObjectState(DBRProgressMonitor monitor) + throws DBCException + { + this.read(); + super.refreshObjectState(monitor); + } + // ----------------- // Properties // ----------------- @Property(viewable = false, editable = false, order = 90, category = ExasolConstants.CAT_BASEOBJECT) - public Boolean getHasDistKey() { + public Boolean getHasDistKey() throws DBCException { + if (! hasRead) + read(); return hasDistKey; } @Property(viewable = false, editable = false, order = 100, category = ExasolConstants.CAT_BASEOBJECT) - public Timestamp getLastCommit() { + public Timestamp getLastCommit() throws DBCException { + if (! hasRead) + read(); return lastCommit; } @Property(viewable = false, editable = false, order = 100, category = ExasolConstants.CAT_DATETIME) - public Timestamp getCreateTime() { + public Timestamp getCreateTime() throws DBCException { + if (! hasRead) + read(); return createTime; } @Property(viewable = false, editable = false, order = 150, category = ExasolConstants.CAT_STATS) - public String getRawsize() { + public String getRawsize() throws DBCException { + if (! hasRead) + read(); return ExasolUtils.humanReadableByteCount(sizeRaw, true); } @Property(viewable = false, editable = false, order = 200, category = ExasolConstants.CAT_STATS) - public String getCompressedsize() { + public String getCompressedsize() throws DBCException { + if (! hasRead) + read(); return ExasolUtils.humanReadableByteCount(sizeCompressed, true); } @Property(viewable = false, editable = false, order = 250, category = ExasolConstants.CAT_STATS) - public float getDeletePercentage() { + public float getDeletePercentage() throws DBCException { + if (! hasRead) + read(); return this.deletePercentage; - } - - + } + // ----------------- // Associations // ----------------- diff --git a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTableBase.java b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTableBase.java index c8b2b966aff51658ed25db367a76f1f2852017d5..b8fcff55a8d96a41a89ff5708232e11fa46bf8a5 100644 --- a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTableBase.java +++ b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/ExasolTableBase.java @@ -46,7 +46,6 @@ import java.util.Collections; public abstract class ExasolTableBase extends JDBCTable implements DBPNamedObject2, DBPRefreshableObject, ExasolStatefulObject { - private String owner; private String remarks; private String objectType; @@ -58,9 +57,8 @@ public abstract class ExasolTableBase extends JDBCTable { +public class ExasolTableUniqueKey extends JDBCTableConstraint implements DBSEntityReferrer { private String owner; private Boolean enabled; @@ -122,5 +123,17 @@ public class ExasolTableUniqueKey extends JDBCTableConstraint { return enabled; } + public boolean hasColumn(ExasolTableColumn column) + { + if (this.columns != null) { + for (ExasolTableKeyColumn constColumn : columns) { + if (constColumn.getAttribute() == column) { + return true; + } + } + } + return false; + } + } diff --git a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableCache.java b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableCache.java index 374def6901ba3d5a26ecfe4e4c43fe3a9eb120ab..5702ddda93d12f1355ac44fa3c89f27e64602ee4 100644 --- a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableCache.java +++ b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableCache.java @@ -24,6 +24,7 @@ import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.ext.exasol.model.ExasolSchema; import org.jkiss.dbeaver.ext.exasol.model.ExasolTable; import org.jkiss.dbeaver.ext.exasol.model.ExasolTableColumn; +import org.jkiss.dbeaver.model.exec.jdbc.JDBCDatabaseMetaData; import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement; import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet; import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession; @@ -35,131 +36,69 @@ import java.sql.SQLException; /** * @author Karl */ -public final class ExasolTableCache extends JDBCStructCache { +public final class ExasolTableCache + extends JDBCStructCache { - private static final String SQL_TABS = - "select * from (" - + "select" + - " table_schema," + - " table_name," + - " table_owner," + - " table_has_distribution_key," + - " table_comment," + - " delete_percentage," + - " o.created," + - " o.last_commit," + - " s.raw_object_size," + - " s.mem_object_size," + - " s.object_type" + - " from" + - " EXA_ALL_OBJECTS o" + - " inner join" + - " EXA_ALL_TABLES T" + - " on" + - " o.root_name = t.table_schema and" + - " t.table_name = o.object_name and" + - " o.object_type = 'TABLE'" + - " inner join " + - " EXA_ALL_OBJECT_SIZES s" + - " on" + - " o.root_name = s.root_name and" + - " o.object_name = s.object_name and" + - " o.object_type = s.object_type" + - " where o.root_name = ? and t.table_schema = ?" + - " union all " - + " select schema_name as table_schema," - + " object_name as table_name," - + " 'SYS' as table_owner," - + " false as table_has_distribution_key," - + " object_comment as table_comment," - + " 0 as delete_percentage," - + " cast( null as timestamp) as created," - + " cast( null as timestamp) as last_commit," - + " 0 as raw_object_size," - + " 0 as mem_object_size," - + " object_type" - + " from SYS.EXA_SYSCAT WHERE object_type = 'TABLE' and schema_name = ?" - + ") as o" - + " order by table_schema,o.table_name"; - // TODO: change to "$ODBCJDBC"."ALL_COLUMNS" - private static final String SQL_COLS_TAB = - "select\r\n" + - " c.*,\r\n" + - " cc.ordinal_position as KEY_SEQ\r\n" + - "from\r\n" + - " \"$ODBCJDBC\".\"ALL_COLUMNS\" c\r\n" + - " left outer join\r\n" + - " EXA_ALL_CONSTRAINT_COLUMNS cc\r\n" + - " on\r\n" + - " c.table_name = cc.constraint_table and\r\n" + - " c.table_schem = cc.constraint_schema and\r\n " + - " cc.constraint_type = 'PRIMARY KEY' and\r\n" + - " cc.COLUMN_NAME = c.COLUMN_NAME\r\n" + - "where\r\n" + - " table_schem = ? and\r\n" + - " table_name = ?\r\n" + - "order by\r\n" + - " c.ordinal_position"; - // TODO: change to "$ODBCJDBC"."ALL_COLUMNS" - private static final String SQL_COLS_ALL = "select\r\n" + - " c.*,\r\n" + - " cc.ordinal_position as KEY_SEQ\r\n" + - "from\r\n" + - " \"$ODBCJDBC\".\"ALL_COLUMNS\" c\r\n" + - " left outer join\r\n" + - " EXA_ALL_CONSTRAINT_COLUMNS cc\r\n" + - " on\r\n" + - " c.table_name = cc.constraint_table and\r\n" + - " c.table_schem = cc.constraint_schema and\r\n " + - " cc.constraint_type = 'PRIMARY KEY' and\r\n" + - " cc.COLUMN_NAME = c.COLUMN_NAME\r\n" + - "where\r\n" + - " table_schem = ? and\r\n" + - "order by\r\n" + - " table_name,c.ordinal_position"; + private static final String SQL_COLS_TAB = "select " + " c.* " + "from " + + " \"$ODBCJDBC\".\"ALL_COLUMNS\" c " + "where " + + " table_schem = ? and " + " table_name = ? " + "order by " + + " c.ordinal_position"; + private static final String SQL_COLS_ALL = "select " + " c.* " + "from " + + " \"$ODBCJDBC\".\"ALL_COLUMNS\" c " + "where " + + " table_schem = ?" + "order by " + + " table_name,c.ordinal_position"; - public ExasolTableCache() { - super("TABLE_NAME"); - } + public ExasolTableCache() + { + super("TABLE_NAME"); + } - @Override - protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull ExasolSchema exasolSchema) throws SQLException { - final JDBCPreparedStatement dbstat = session.prepareStatement(SQL_TABS); - dbstat.setString(1, exasolSchema.getName()); - dbstat.setString(2, exasolSchema.getName()); - dbstat.setString(3, exasolSchema.getName()); - return dbstat; - } + @Override + protected JDBCStatement prepareObjectsStatement( + @NotNull JDBCSession session, @NotNull ExasolSchema exasolSchema) + throws SQLException + { + JDBCDatabaseMetaData meta = session.getMetaData(); - @Override - protected JDBCStatement prepareChildrenStatement(@NotNull JDBCSession session, @NotNull ExasolSchema exasolSchema, @Nullable ExasolTable exasolTable) - throws SQLException { - String sql; + return meta.getTables("EXA_DB", exasolSchema.getName(), null, + new String[] { "TABLE" }).getSourceStatement(); + } - if (exasolTable != null) - sql = SQL_COLS_TAB; - else - sql = SQL_COLS_ALL; + @Override + protected JDBCStatement prepareChildrenStatement( + @NotNull JDBCSession session, @NotNull ExasolSchema exasolSchema, + @Nullable ExasolTable exasolTable) throws SQLException + { + String sql; - JDBCPreparedStatement dbstat = session.prepareStatement(sql); - dbstat.setString(1, exasolSchema.getName()); - if (exasolTable != null) - dbstat.setString(2, exasolTable.getName()); + if (exasolTable != null) + sql = SQL_COLS_TAB; + else + sql = SQL_COLS_ALL; - return dbstat; - } + JDBCPreparedStatement dbstat = session.prepareStatement(sql); + dbstat.setString(1, exasolSchema.getName()); + if (exasolTable != null) + dbstat.setString(2, exasolTable.getName()); - @Override - protected ExasolTableColumn fetchChild(@NotNull JDBCSession session, @NotNull ExasolSchema owner, @NotNull ExasolTable parent, - JDBCResultSet dbResult) throws SQLException, DBException { - return new ExasolTableColumn(session.getProgressMonitor(), parent, dbResult); - } + return dbstat; + } + @Override + protected ExasolTableColumn fetchChild(@NotNull JDBCSession session, + @NotNull ExasolSchema owner, @NotNull ExasolTable parent, + JDBCResultSet dbResult) throws SQLException, DBException + { + return new ExasolTableColumn(session.getProgressMonitor(), parent, + dbResult); + } - @Override - protected ExasolTable fetchObject(@NotNull JDBCSession session, @NotNull ExasolSchema owner, @NotNull JDBCResultSet resultSet) - throws SQLException, DBException { - return new ExasolTable(session.getProgressMonitor(), owner, resultSet); - } + @Override + protected ExasolTable fetchObject(@NotNull JDBCSession session, + @NotNull ExasolSchema owner, @NotNull JDBCResultSet resultSet) + throws SQLException, DBException + { + return new ExasolTable(session.getProgressMonitor(), owner, resultSet); + } } diff --git a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableUniqueKeyCache.java b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableUniqueKeyCache.java index afe1173f43127804b4e37704ca6255fe05618f80..f21003f40c8cdbb960f84d1957c69515e43e2357 100644 --- a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableUniqueKeyCache.java +++ b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolTableUniqueKeyCache.java @@ -115,9 +115,18 @@ public final class ExasolTableUniqueKeyCache log.debug("Column '" + columnName + "' not found in table '" + exasolTable.getFullyQualifiedName(DBPEvaluationContext.UI) + "' ??"); return null; } else { + /* verify that the column is not null -> even though it is not in the meta data + * Exasol always verify not null for columns in a PK + * this is necessary for the automatic unique identifiers detection to work + */ + tableColumn.setRequired(true); return new ExasolTableKeyColumn[]{ new ExasolTableKeyColumn(object, tableColumn, JDBCUtils.safeGetInteger(dbResult, "ORDINAL_POSITION")) }; + + + + } } diff --git a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolViewCache.java b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolViewCache.java index 36e2f58bcc5366b49a0a5a2bb21490157502aa29..f05b72ea4d95ba74c51113d55c5792490704e320 100644 --- a/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolViewCache.java +++ b/plugins/org.jkiss.dbeaver.ext.exasol/src/org/jkiss/dbeaver/ext/exasol/model/cache/ExasolViewCache.java @@ -63,7 +63,7 @@ public class ExasolViewCache extends JDBCStructCache