org.h2.table.InformationSchemaTableLegacy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of h2-mvstore Show documentation
Show all versions of h2-mvstore Show documentation
Fork of h2database to maintain Java 8 compatibility
The newest version!
/*
* Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.table;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import org.h2.command.Command;
import org.h2.command.ParserBase;
import org.h2.command.dml.Help;
import org.h2.constraint.Constraint;
import org.h2.constraint.Constraint.Type;
import org.h2.constraint.ConstraintActionType;
import org.h2.constraint.ConstraintCheck;
import org.h2.constraint.ConstraintDomain;
import org.h2.constraint.ConstraintReferential;
import org.h2.constraint.ConstraintUnique;
import org.h2.engine.Constants;
import org.h2.engine.DbObject;
import org.h2.engine.QueryStatisticsData;
import org.h2.engine.Right;
import org.h2.engine.RightOwner;
import org.h2.engine.Role;
import org.h2.engine.SessionLocal;
import org.h2.engine.SessionLocal.State;
import org.h2.engine.Setting;
import org.h2.engine.User;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor;
import org.h2.expression.ValueExpression;
import org.h2.index.Index;
import org.h2.index.MetaIndex;
import org.h2.message.DbException;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.result.SortOrder;
import org.h2.schema.Constant;
import org.h2.schema.Domain;
import org.h2.schema.FunctionAlias;
import org.h2.schema.FunctionAlias.JavaMethod;
import org.h2.schema.Schema;
import org.h2.schema.SchemaObject;
import org.h2.schema.Sequence;
import org.h2.schema.TriggerObject;
import org.h2.schema.UserDefinedFunction;
import org.h2.store.InDoubtTransaction;
import org.h2.tools.Csv;
import org.h2.util.DateTimeUtils;
import org.h2.util.HasSQL;
import org.h2.util.MathUtils;
import org.h2.util.NetworkConnectionInfo;
import org.h2.util.StringUtils;
import org.h2.util.TimeZoneProvider;
import org.h2.util.Utils;
import org.h2.value.CompareMode;
import org.h2.value.DataType;
import org.h2.value.TypeInfo;
import org.h2.value.Value;
import org.h2.value.ValueBigint;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueDouble;
import org.h2.value.ValueInteger;
import org.h2.value.ValueSmallint;
import org.h2.value.ValueToObjectConverter2;
/**
* This class is responsible to build the legacy variant of INFORMATION_SCHEMA
* tables.
*/
public final class InformationSchemaTableLegacy extends MetaTable {
private static final String CHARACTER_SET_NAME = "Unicode";
private static final int TABLES = 0;
private static final int COLUMNS = TABLES + 1;
private static final int INDEXES = COLUMNS + 1;
private static final int TABLE_TYPES = INDEXES + 1;
private static final int TYPE_INFO = TABLE_TYPES + 1;
private static final int CATALOGS = TYPE_INFO + 1;
private static final int SETTINGS = CATALOGS + 1;
private static final int HELP = SETTINGS + 1;
private static final int SEQUENCES = HELP + 1;
private static final int USERS = SEQUENCES + 1;
private static final int ROLES = USERS + 1;
private static final int RIGHTS = ROLES + 1;
private static final int FUNCTION_ALIASES = RIGHTS + 1;
private static final int SCHEMATA = FUNCTION_ALIASES + 1;
private static final int TABLE_PRIVILEGES = SCHEMATA + 1;
private static final int COLUMN_PRIVILEGES = TABLE_PRIVILEGES + 1;
private static final int COLLATIONS = COLUMN_PRIVILEGES + 1;
private static final int VIEWS = COLLATIONS + 1;
private static final int IN_DOUBT = VIEWS + 1;
private static final int CROSS_REFERENCES = IN_DOUBT + 1;
private static final int FUNCTION_COLUMNS = CROSS_REFERENCES + 1;
private static final int CONSTRAINTS = FUNCTION_COLUMNS + 1;
private static final int CONSTANTS = CONSTRAINTS + 1;
private static final int DOMAINS = CONSTANTS + 1;
private static final int TRIGGERS = DOMAINS + 1;
private static final int SESSIONS = TRIGGERS + 1;
private static final int LOCKS = SESSIONS + 1;
private static final int SESSION_STATE = LOCKS + 1;
private static final int QUERY_STATISTICS = SESSION_STATE + 1;
private static final int SYNONYMS = QUERY_STATISTICS + 1;
private static final int TABLE_CONSTRAINTS = SYNONYMS + 1;
private static final int DOMAIN_CONSTRAINTS = TABLE_CONSTRAINTS + 1;
private static final int KEY_COLUMN_USAGE = DOMAIN_CONSTRAINTS + 1;
private static final int REFERENTIAL_CONSTRAINTS = KEY_COLUMN_USAGE + 1;
private static final int CHECK_CONSTRAINTS = REFERENTIAL_CONSTRAINTS + 1;
private static final int CONSTRAINT_COLUMN_USAGE = CHECK_CONSTRAINTS + 1;
/**
* The number of meta table types. Supported meta table types are
* {@code 0..META_TABLE_TYPE_COUNT - 1}.
*/
public static final int META_TABLE_TYPE_COUNT = CONSTRAINT_COLUMN_USAGE + 1;
/**
* Create a new metadata table.
*
* @param schema the schema
* @param id the object id
* @param type the meta table type
*/
public InformationSchemaTableLegacy(Schema schema, int id, int type) {
super(schema, id, type);
Column[] cols;
String indexColumnName = null;
switch (type) {
case TABLES:
setMetaTableName("TABLES");
cols = new Column[] {
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("TABLE_TYPE"), //
// extensions
column("STORAGE_TYPE"), //
column("SQL"), //
column("REMARKS"), //
column("LAST_MODIFICATION", TypeInfo.TYPE_BIGINT), //
column("ID", TypeInfo.TYPE_INTEGER), //
column("TYPE_NAME"), //
column("TABLE_CLASS"), //
column("ROW_COUNT_ESTIMATE", TypeInfo.TYPE_BIGINT), //
};
indexColumnName = "TABLE_NAME";
break;
case COLUMNS:
setMetaTableName("COLUMNS");
cols = new Column[] {
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("COLUMN_NAME"), //
column("ORDINAL_POSITION", TypeInfo.TYPE_INTEGER), //
column("COLUMN_DEFAULT"), //
column("IS_NULLABLE"), //
column("DATA_TYPE", TypeInfo.TYPE_INTEGER), //
column("CHARACTER_MAXIMUM_LENGTH", TypeInfo.TYPE_INTEGER), //
column("CHARACTER_OCTET_LENGTH", TypeInfo.TYPE_INTEGER), //
column("NUMERIC_PRECISION", TypeInfo.TYPE_INTEGER), //
column("NUMERIC_PRECISION_RADIX", TypeInfo.TYPE_INTEGER), //
column("NUMERIC_SCALE", TypeInfo.TYPE_INTEGER), //
column("DATETIME_PRECISION", TypeInfo.TYPE_INTEGER), //
column("INTERVAL_TYPE"), //
column("INTERVAL_PRECISION", TypeInfo.TYPE_INTEGER), //
column("CHARACTER_SET_NAME"), //
column("COLLATION_NAME"), //
column("DOMAIN_CATALOG"), //
column("DOMAIN_SCHEMA"), //
column("DOMAIN_NAME"), //
column("IS_GENERATED"), //
column("GENERATION_EXPRESSION"), //
// extensions
column("TYPE_NAME"), //
column("NULLABLE", TypeInfo.TYPE_INTEGER), //
column("IS_COMPUTED", TypeInfo.TYPE_BOOLEAN), //
column("SELECTIVITY", TypeInfo.TYPE_INTEGER), //
column("SEQUENCE_NAME"), //
column("REMARKS"), //
column("SOURCE_DATA_TYPE", TypeInfo.TYPE_SMALLINT), //
column("COLUMN_TYPE"), //
column("COLUMN_ON_UPDATE"), //
column("IS_VISIBLE"), //
// compatibility
column("CHECK_CONSTRAINT"), //
};
indexColumnName = "TABLE_NAME";
break;
case INDEXES:
setMetaTableName("INDEXES");
cols = new Column[] {
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("NON_UNIQUE", TypeInfo.TYPE_BOOLEAN), //
column("INDEX_NAME"), //
column("ORDINAL_POSITION", TypeInfo.TYPE_SMALLINT), //
column("COLUMN_NAME"), //
column("CARDINALITY", TypeInfo.TYPE_INTEGER), //
column("PRIMARY_KEY", TypeInfo.TYPE_BOOLEAN), //
column("INDEX_TYPE_NAME"), //
column("IS_GENERATED", TypeInfo.TYPE_BOOLEAN), //
column("INDEX_TYPE", TypeInfo.TYPE_SMALLINT), //
column("ASC_OR_DESC"), //
column("PAGES", TypeInfo.TYPE_INTEGER), //
column("FILTER_CONDITION"), //
column("REMARKS"), //
column("SQL"), //
column("ID", TypeInfo.TYPE_INTEGER), //
column("SORT_TYPE", TypeInfo.TYPE_INTEGER), //
column("CONSTRAINT_NAME"), //
column("INDEX_CLASS"), //
};
indexColumnName = "TABLE_NAME";
break;
case TABLE_TYPES:
setMetaTableName("TABLE_TYPES");
cols = new Column[] {
column("TYPE"), //
};
break;
case TYPE_INFO:
setMetaTableName("TYPE_INFO");
cols = new Column[] {
column("TYPE_NAME"), //
column("DATA_TYPE", TypeInfo.TYPE_INTEGER), //
column("PRECISION", TypeInfo.TYPE_INTEGER), //
column("PREFIX"), //
column("SUFFIX"), //
column("PARAMS"), //
column("AUTO_INCREMENT", TypeInfo.TYPE_BOOLEAN), //
column("MINIMUM_SCALE", TypeInfo.TYPE_SMALLINT), //
column("MAXIMUM_SCALE", TypeInfo.TYPE_SMALLINT), //
column("RADIX", TypeInfo.TYPE_INTEGER), //
column("POS", TypeInfo.TYPE_INTEGER), //
column("CASE_SENSITIVE", TypeInfo.TYPE_BOOLEAN), //
column("NULLABLE", TypeInfo.TYPE_SMALLINT), //
column("SEARCHABLE", TypeInfo.TYPE_SMALLINT), //
};
break;
case CATALOGS:
setMetaTableName("CATALOGS");
cols = new Column[] {
column("CATALOG_NAME"), //
};
break;
case SETTINGS:
setMetaTableName("SETTINGS");
cols = new Column[] {
column("NAME"), //
column("VALUE"), //
};
break;
case HELP:
setMetaTableName("HELP");
cols = new Column[] {
column("ID", TypeInfo.TYPE_INTEGER), //
column("SECTION"), //
column("TOPIC"), //
column("SYNTAX"), //
column("TEXT"), //
};
break;
case SEQUENCES:
setMetaTableName("SEQUENCES");
cols = new Column[] {
column("SEQUENCE_CATALOG"), //
column("SEQUENCE_SCHEMA"), //
column("SEQUENCE_NAME"), //
column("DATA_TYPE"), //
column("NUMERIC_PRECISION", TypeInfo.TYPE_INTEGER), //
column("NUMERIC_PRECISION_RADIX", TypeInfo.TYPE_INTEGER), //
column("NUMERIC_SCALE", TypeInfo.TYPE_INTEGER), //
column("START_VALUE", TypeInfo.TYPE_BIGINT), //
column("MINIMUM_VALUE", TypeInfo.TYPE_BIGINT), //
column("MAXIMUM_VALUE", TypeInfo.TYPE_BIGINT), //
column("INCREMENT", TypeInfo.TYPE_BIGINT), //
column("CYCLE_OPTION"), //
column("DECLARED_DATA_TYPE"), //
column("DECLARED_NUMERIC_PRECISION", TypeInfo.TYPE_INTEGER), //
column("DECLARED_NUMERIC_SCALE", TypeInfo.TYPE_INTEGER), //
column("CURRENT_VALUE", TypeInfo.TYPE_BIGINT), //
column("IS_GENERATED", TypeInfo.TYPE_BOOLEAN), //
column("REMARKS"), //
column("CACHE", TypeInfo.TYPE_BIGINT), //
column("ID", TypeInfo.TYPE_INTEGER), //
// compatibility
column("MIN_VALUE", TypeInfo.TYPE_BIGINT), //
column("MAX_VALUE", TypeInfo.TYPE_BIGINT), //
column("IS_CYCLE", TypeInfo.TYPE_BOOLEAN), //
};
break;
case USERS:
setMetaTableName("USERS");
cols = new Column[] {
column("NAME"), //
column("ADMIN"), //
column("REMARKS"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
break;
case ROLES:
setMetaTableName("ROLES");
cols = new Column[] {
column("NAME"), //
column("REMARKS"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
break;
case RIGHTS:
setMetaTableName("RIGHTS");
cols = new Column[] {
column("GRANTEE"), //
column("GRANTEETYPE"), //
column("GRANTEDROLE"), //
column("RIGHTS"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
indexColumnName = "TABLE_NAME";
break;
case FUNCTION_ALIASES:
setMetaTableName("FUNCTION_ALIASES");
cols = new Column[] {
column("ALIAS_CATALOG"), //
column("ALIAS_SCHEMA"), //
column("ALIAS_NAME"), //
column("JAVA_CLASS"), //
column("JAVA_METHOD"), //
column("DATA_TYPE", TypeInfo.TYPE_INTEGER), //
column("TYPE_NAME"), //
column("COLUMN_COUNT", TypeInfo.TYPE_INTEGER), //
column("RETURNS_RESULT", TypeInfo.TYPE_SMALLINT), //
column("REMARKS"), //
column("ID", TypeInfo.TYPE_INTEGER), //
column("SOURCE"), //
};
break;
case FUNCTION_COLUMNS:
setMetaTableName("FUNCTION_COLUMNS");
cols = new Column[] {
column("ALIAS_CATALOG"), //
column("ALIAS_SCHEMA"), //
column("ALIAS_NAME"), //
column("JAVA_CLASS"), //
column("JAVA_METHOD"), //
column("COLUMN_COUNT", TypeInfo.TYPE_INTEGER), //
column("POS", TypeInfo.TYPE_INTEGER), //
column("COLUMN_NAME"), //
column("DATA_TYPE", TypeInfo.TYPE_INTEGER), //
column("TYPE_NAME"), //
column("PRECISION", TypeInfo.TYPE_INTEGER), //
column("SCALE", TypeInfo.TYPE_SMALLINT), //
column("RADIX", TypeInfo.TYPE_SMALLINT), //
column("NULLABLE", TypeInfo.TYPE_SMALLINT), //
column("COLUMN_TYPE", TypeInfo.TYPE_SMALLINT), //
column("REMARKS"), //
column("COLUMN_DEFAULT"), //
};
break;
case SCHEMATA:
setMetaTableName("SCHEMATA");
cols = new Column[] {
column("CATALOG_NAME"), //
column("SCHEMA_NAME"), //
column("SCHEMA_OWNER"), //
column("DEFAULT_CHARACTER_SET_NAME"), //
column("DEFAULT_COLLATION_NAME"), //
column("IS_DEFAULT", TypeInfo.TYPE_BOOLEAN), //
column("REMARKS"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
break;
case TABLE_PRIVILEGES:
setMetaTableName("TABLE_PRIVILEGES");
cols = new Column[] {
column("GRANTOR"), //
column("GRANTEE"), //
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("PRIVILEGE_TYPE"), //
column("IS_GRANTABLE"), //
};
indexColumnName = "TABLE_NAME";
break;
case COLUMN_PRIVILEGES:
setMetaTableName("COLUMN_PRIVILEGES");
cols = new Column[] {
column("GRANTOR"), //
column("GRANTEE"), //
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("COLUMN_NAME"), //
column("PRIVILEGE_TYPE"), //
column("IS_GRANTABLE"), //
};
indexColumnName = "TABLE_NAME";
break;
case COLLATIONS:
setMetaTableName("COLLATIONS");
cols = new Column[] {
column("NAME"), //
column("KEY"), //
};
break;
case VIEWS:
setMetaTableName("VIEWS");
cols = new Column[] {
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("VIEW_DEFINITION"), //
column("CHECK_OPTION"), //
column("IS_UPDATABLE"), //
column("STATUS"), //
column("REMARKS"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
indexColumnName = "TABLE_NAME";
break;
case IN_DOUBT:
setMetaTableName("IN_DOUBT");
cols = new Column[] {
column("TRANSACTION"), //
column("STATE"), //
};
break;
case CROSS_REFERENCES:
setMetaTableName("CROSS_REFERENCES");
cols = new Column[] {
column("PKTABLE_CATALOG"), //
column("PKTABLE_SCHEMA"), //
column("PKTABLE_NAME"), //
column("PKCOLUMN_NAME"), //
column("FKTABLE_CATALOG"), //
column("FKTABLE_SCHEMA"), //
column("FKTABLE_NAME"), //
column("FKCOLUMN_NAME"), //
column("ORDINAL_POSITION", TypeInfo.TYPE_SMALLINT), //
column("UPDATE_RULE", TypeInfo.TYPE_SMALLINT), //
column("DELETE_RULE", TypeInfo.TYPE_SMALLINT), //
column("FK_NAME"), //
column("PK_NAME"), //
column("DEFERRABILITY", TypeInfo.TYPE_SMALLINT), //
};
indexColumnName = "PKTABLE_NAME";
break;
case CONSTRAINTS:
setMetaTableName("CONSTRAINTS");
cols = new Column[] {
column("CONSTRAINT_CATALOG"), //
column("CONSTRAINT_SCHEMA"), //
column("CONSTRAINT_NAME"), //
column("CONSTRAINT_TYPE"), //
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("UNIQUE_INDEX_NAME"), //
column("CHECK_EXPRESSION"), //
column("COLUMN_LIST"), //
column("REMARKS"), //
column("SQL"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
indexColumnName = "TABLE_NAME";
break;
case CONSTANTS:
setMetaTableName("CONSTANTS");
cols = new Column[] {
column("CONSTANT_CATALOG"), //
column("CONSTANT_SCHEMA"), //
column("CONSTANT_NAME"), //
column("DATA_TYPE", TypeInfo.TYPE_INTEGER), //
column("REMARKS"), //
column("SQL"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
break;
case DOMAINS:
setMetaTableName("DOMAINS");
cols = new Column[] {
column("DOMAIN_CATALOG"), //
column("DOMAIN_SCHEMA"), //
column("DOMAIN_NAME"), //
column("DOMAIN_DEFAULT"), //
column("DOMAIN_ON_UPDATE"), //
column("DATA_TYPE", TypeInfo.TYPE_INTEGER), //
column("PRECISION", TypeInfo.TYPE_INTEGER), //
column("SCALE", TypeInfo.TYPE_INTEGER), //
column("TYPE_NAME"), //
column("PARENT_DOMAIN_CATALOG"), //
column("PARENT_DOMAIN_SCHEMA"), //
column("PARENT_DOMAIN_NAME"), //
column("SELECTIVITY", TypeInfo.TYPE_INTEGER), //
column("REMARKS"), //
column("SQL"), //
column("ID", TypeInfo.TYPE_INTEGER), //
// compatibility
column("COLUMN_DEFAULT"), //
column("IS_NULLABLE"), //
column("CHECK_CONSTRAINT"), //
};
break;
case TRIGGERS:
setMetaTableName("TRIGGERS");
cols = new Column[] {
column("TRIGGER_CATALOG"), //
column("TRIGGER_SCHEMA"), //
column("TRIGGER_NAME"), //
column("TRIGGER_TYPE"), //
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("BEFORE", TypeInfo.TYPE_BOOLEAN), //
column("JAVA_CLASS"), //
column("QUEUE_SIZE", TypeInfo.TYPE_INTEGER), //
column("NO_WAIT", TypeInfo.TYPE_BOOLEAN), //
column("REMARKS"), //
column("SQL"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
break;
case SESSIONS: {
setMetaTableName("SESSIONS");
cols = new Column[] {
column("ID", TypeInfo.TYPE_INTEGER), //
column("USER_NAME"), //
column("SERVER"), //
column("CLIENT_ADDR"), //
column("CLIENT_INFO"), //
column("SESSION_START", TypeInfo.TYPE_TIMESTAMP_TZ), //
column("ISOLATION_LEVEL"), //
column("STATEMENT"), //
column("STATEMENT_START", TypeInfo.TYPE_TIMESTAMP_TZ), //
column("CONTAINS_UNCOMMITTED", TypeInfo.TYPE_BOOLEAN), //
column("STATE"), //
column("BLOCKER_ID", TypeInfo.TYPE_INTEGER), //
column("SLEEP_SINCE", TypeInfo.TYPE_TIMESTAMP_TZ), //
};
break;
}
case LOCKS: {
setMetaTableName("LOCKS");
cols = new Column[] {
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("SESSION_ID", TypeInfo.TYPE_INTEGER), //
column("LOCK_TYPE"), //
};
break;
}
case SESSION_STATE: {
setMetaTableName("SESSION_STATE");
cols = new Column[] {
column("KEY"), //
column("SQL"), //
};
break;
}
case QUERY_STATISTICS: {
setMetaTableName("QUERY_STATISTICS");
cols = new Column[] {
column("SQL_STATEMENT"), //
column("EXECUTION_COUNT", TypeInfo.TYPE_INTEGER), //
column("MIN_EXECUTION_TIME", TypeInfo.TYPE_DOUBLE), //
column("MAX_EXECUTION_TIME", TypeInfo.TYPE_DOUBLE), //
column("CUMULATIVE_EXECUTION_TIME", TypeInfo.TYPE_DOUBLE), //
column("AVERAGE_EXECUTION_TIME", TypeInfo.TYPE_DOUBLE), //
column("STD_DEV_EXECUTION_TIME", TypeInfo.TYPE_DOUBLE), //
column("MIN_ROW_COUNT", TypeInfo.TYPE_BIGINT), //
column("MAX_ROW_COUNT", TypeInfo.TYPE_BIGINT), //
column("CUMULATIVE_ROW_COUNT", TypeInfo.TYPE_BIGINT), //
column("AVERAGE_ROW_COUNT", TypeInfo.TYPE_DOUBLE), //
column("STD_DEV_ROW_COUNT", TypeInfo.TYPE_DOUBLE), //
};
break;
}
case SYNONYMS: {
setMetaTableName("SYNONYMS");
cols = new Column[] {
column("SYNONYM_CATALOG"), //
column("SYNONYM_SCHEMA"), //
column("SYNONYM_NAME"), //
column("SYNONYM_FOR"), //
column("SYNONYM_FOR_SCHEMA"), //
column("TYPE_NAME"), //
column("STATUS"), //
column("REMARKS"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
indexColumnName = "SYNONYM_NAME";
break;
}
case TABLE_CONSTRAINTS: {
setMetaTableName("TABLE_CONSTRAINTS");
cols = new Column[] {
column("CONSTRAINT_CATALOG"), //
column("CONSTRAINT_SCHEMA"), //
column("CONSTRAINT_NAME"), //
column("CONSTRAINT_TYPE"), //
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("IS_DEFERRABLE"), //
column("INITIALLY_DEFERRED"), //
column("REMARKS"), //
column("SQL"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
indexColumnName = "TABLE_NAME";
break;
}
case DOMAIN_CONSTRAINTS: {
setMetaTableName("DOMAIN_CONSTRAINTS");
cols = new Column[] {
column("CONSTRAINT_CATALOG"), //
column("CONSTRAINT_SCHEMA"), //
column("CONSTRAINT_NAME"), //
column("DOMAIN_CATALOG"), //
column("DOMAIN_SCHEMA"), //
column("DOMAIN_NAME"), //
column("IS_DEFERRABLE"), //
column("INITIALLY_DEFERRED"), //
column("REMARKS"), //
column("SQL"), //
column("ID", TypeInfo.TYPE_INTEGER), //
};
break;
}
case KEY_COLUMN_USAGE: {
setMetaTableName("KEY_COLUMN_USAGE");
cols = new Column[] {
column("CONSTRAINT_CATALOG"), //
column("CONSTRAINT_SCHEMA"), //
column("CONSTRAINT_NAME"), //
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("COLUMN_NAME"), //
column("ORDINAL_POSITION", TypeInfo.TYPE_INTEGER), //
column("POSITION_IN_UNIQUE_CONSTRAINT", TypeInfo.TYPE_INTEGER), //
column("INDEX_CATALOG"), //
column("INDEX_SCHEMA"), //
column("INDEX_NAME"), //
};
indexColumnName = "TABLE_NAME";
break;
}
case REFERENTIAL_CONSTRAINTS: {
setMetaTableName("REFERENTIAL_CONSTRAINTS");
cols = new Column[] {
column("CONSTRAINT_CATALOG"), //
column("CONSTRAINT_SCHEMA"), //
column("CONSTRAINT_NAME"), //
column("UNIQUE_CONSTRAINT_CATALOG"), //
column("UNIQUE_CONSTRAINT_SCHEMA"), //
column("UNIQUE_CONSTRAINT_NAME"), //
column("MATCH_OPTION"), //
column("UPDATE_RULE"), //
column("DELETE_RULE"), //
};
break;
}
case CHECK_CONSTRAINTS: {
setMetaTableName("CHECK_CONSTRAINTS");
cols = new Column[] {
column("CONSTRAINT_CATALOG"), //
column("CONSTRAINT_SCHEMA"), //
column("CONSTRAINT_NAME"), //
column("CHECK_CLAUSE"), //
};
break;
}
case CONSTRAINT_COLUMN_USAGE: {
setMetaTableName("CONSTRAINT_COLUMN_USAGE");
cols = new Column[] {
column("TABLE_CATALOG"), //
column("TABLE_SCHEMA"), //
column("TABLE_NAME"), //
column("COLUMN_NAME"), //
column("CONSTRAINT_CATALOG"), //
column("CONSTRAINT_SCHEMA"), //
column("CONSTRAINT_NAME"), //
};
indexColumnName = "TABLE_NAME";
break;
}
default:
throw DbException.getInternalError("type=" + type);
}
setColumns(cols);
if (indexColumnName == null) {
indexColumn = -1;
metaIndex = null;
} else {
indexColumn = getColumn(database.sysIdentifier(indexColumnName)).getColumnId();
IndexColumn[] indexCols = IndexColumn.wrap(
new Column[] { cols[indexColumn] });
metaIndex = new MetaIndex(this, indexCols, false);
}
}
private static String replaceNullWithEmpty(String s) {
return s == null ? "" : s;
}
@Override
public ArrayList generateRows(SessionLocal session, SearchRow first, SearchRow last) {
Value indexFrom = null, indexTo = null;
if (indexColumn >= 0) {
if (first != null) {
indexFrom = first.getValue(indexColumn);
}
if (last != null) {
indexTo = last.getValue(indexColumn);
}
}
ArrayList rows = Utils.newSmallArrayList();
String catalog = database.getShortName();
boolean admin = session.getUser().isAdmin();
switch (type) {
case TABLES: {
for (Table table : getAllTables(session)) {
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
if (hideTable(table, session)) {
continue;
}
String storageType;
if (table.isTemporary()) {
if (table.isGlobalTemporary()) {
storageType = "GLOBAL TEMPORARY";
} else {
storageType = "LOCAL TEMPORARY";
}
} else {
storageType = table.isPersistIndexes() ?
"CACHED" : "MEMORY";
}
String sql = table.getCreateSQL();
if (!admin) {
if (sql != null && sql.contains(DbException.HIDE_SQL)) {
// hide the password of linked tables
sql = "-";
}
}
add(session,
rows,
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
tableName,
// TABLE_TYPE
table.getTableType().toString(),
// STORAGE_TYPE
storageType,
// SQL
sql,
// REMARKS
replaceNullWithEmpty(table.getComment()),
// LAST_MODIFICATION
ValueBigint.get(table.getMaxDataModificationId()),
// ID
ValueInteger.get(table.getId()),
// TYPE_NAME
null,
// TABLE_CLASS
table.getClass().getName(),
// ROW_COUNT_ESTIMATE
ValueBigint.get(table.getRowCountApproximation(session))
);
}
break;
}
case COLUMNS: {
// reduce the number of tables to scan - makes some metadata queries
// 10x faster
final ArrayList tablesToList;
if (indexFrom != null && indexFrom.equals(indexTo)) {
String tableName = indexFrom.getString();
if (tableName == null) {
break;
}
tablesToList = getTablesByName(session, tableName);
} else {
tablesToList = getAllTables(session);
}
for (Table table : tablesToList) {
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
if (hideTable(table, session)) {
continue;
}
Column[] cols = table.getColumns();
String collation = database.getCompareMode().getName();
for (int j = 0; j < cols.length; j++) {
Column c = cols[j];
Domain domain = c.getDomain();
TypeInfo typeInfo = c.getType();
ValueInteger precision = ValueInteger.get(MathUtils.convertLongToInt(typeInfo.getPrecision()));
ValueInteger scale = ValueInteger.get(typeInfo.getScale());
Sequence sequence = c.getSequence();
boolean hasDateTimePrecision;
int type = typeInfo.getValueType();
switch (type) {
case Value.TIME:
case Value.TIME_TZ:
case Value.DATE:
case Value.TIMESTAMP:
case Value.TIMESTAMP_TZ:
case Value.INTERVAL_SECOND:
case Value.INTERVAL_DAY_TO_SECOND:
case Value.INTERVAL_HOUR_TO_SECOND:
case Value.INTERVAL_MINUTE_TO_SECOND:
hasDateTimePrecision = true;
break;
default:
hasDateTimePrecision = false;
}
boolean isGenerated = c.isGenerated();
boolean isInterval = DataType.isIntervalType(type);
String createSQLWithoutName = c.getCreateSQLWithoutName();
add(session,
rows,
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
tableName,
// COLUMN_NAME
c.getName(),
// ORDINAL_POSITION
ValueInteger.get(j + 1),
// COLUMN_DEFAULT
isGenerated ? null : c.getDefaultSQL(),
// IS_NULLABLE
c.isNullable() ? "YES" : "NO",
// DATA_TYPE
ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)),
// CHARACTER_MAXIMUM_LENGTH
precision,
// CHARACTER_OCTET_LENGTH
precision,
// NUMERIC_PRECISION
precision,
// NUMERIC_PRECISION_RADIX
ValueInteger.get(10),
// NUMERIC_SCALE
scale,
// DATETIME_PRECISION
hasDateTimePrecision ? scale : null,
// INTERVAL_TYPE
isInterval ? createSQLWithoutName.substring(9) : null,
// INTERVAL_PRECISION
isInterval ? precision : null,
// CHARACTER_SET_NAME
CHARACTER_SET_NAME,
// COLLATION_NAME
collation,
// DOMAIN_CATALOG
domain != null ? catalog : null,
// DOMAIN_SCHEMA
domain != null ? domain.getSchema().getName() : null,
// DOMAIN_NAME
domain != null ? domain.getName() : null,
// IS_GENERATED
isGenerated ? "ALWAYS" : "NEVER",
// GENERATION_EXPRESSION
isGenerated ? c.getDefaultSQL() : null,
// TYPE_NAME
identifier(isInterval ? "INTERVAL" : typeInfo.getDeclaredTypeName()),
// NULLABLE
ValueInteger.get(c.isNullable()
? DatabaseMetaData.columnNullable : DatabaseMetaData.columnNoNulls),
// IS_COMPUTED
ValueBoolean.get(isGenerated),
// SELECTIVITY
ValueInteger.get(c.getSelectivity()),
// SEQUENCE_NAME
sequence == null ? null : sequence.getName(),
// REMARKS
replaceNullWithEmpty(c.getComment()),
// SOURCE_DATA_TYPE
// SMALLINT
null,
// COLUMN_TYPE
createSQLWithoutName,
// COLUMN_ON_UPDATE
c.getOnUpdateSQL(),
// IS_VISIBLE
ValueBoolean.get(c.getVisible()),
// CHECK_CONSTRAINT
null
);
}
}
break;
}
case INDEXES: {
// reduce the number of tables to scan - makes some metadata queries
// 10x faster
final ArrayList tablesToList;
if (indexFrom != null && indexFrom.equals(indexTo)) {
String tableName = indexFrom.getString();
if (tableName == null) {
break;
}
tablesToList = getTablesByName(session, tableName);
} else {
tablesToList = getAllTables(session);
}
for (Table table : tablesToList) {
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
if (hideTable(table, session)) {
continue;
}
ArrayList indexes = table.getIndexes();
ArrayList constraints = table.getConstraints();
for (int j = 0; indexes != null && j < indexes.size(); j++) {
Index index = indexes.get(j);
if (index.getCreateSQL() == null) {
continue;
}
String constraintName = null;
for (int k = 0; constraints != null && k < constraints.size(); k++) {
Constraint constraint = constraints.get(k);
if (constraint.usesIndex(index)) {
if (index.getIndexType().isPrimaryKey()) {
if (constraint.getConstraintType() == Constraint.Type.PRIMARY_KEY) {
constraintName = constraint.getName();
}
} else {
constraintName = constraint.getName();
}
}
}
IndexColumn[] cols = index.getIndexColumns();
int uniqueColumnCount = index.getUniqueColumnCount();
String indexClass = index.getClass().getName();
for (int k = 0; k < cols.length; k++) {
IndexColumn idxCol = cols[k];
Column column = idxCol.column;
add(session,
rows,
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
tableName,
// NON_UNIQUE
ValueBoolean.get(k >= uniqueColumnCount),
// INDEX_NAME
index.getName(),
// ORDINAL_POSITION
ValueSmallint.get((short) (k + 1)),
// COLUMN_NAME
column.getName(),
// CARDINALITY
ValueInteger.get(0),
// PRIMARY_KEY
ValueBoolean.get(index.getIndexType().isPrimaryKey()),
// INDEX_TYPE_NAME
index.getIndexType().getSQL(false),
// IS_GENERATED
ValueBoolean.get(index.getIndexType().getBelongsToConstraint()),
// INDEX_TYPE
ValueSmallint.get(DatabaseMetaData.tableIndexOther),
// ASC_OR_DESC
(idxCol.sortType & SortOrder.DESCENDING) != 0 ? "D" : "A",
// PAGES
ValueInteger.get(0),
// FILTER_CONDITION
"",
// REMARKS
replaceNullWithEmpty(index.getComment()),
// SQL
index.getCreateSQL(),
// ID
ValueInteger.get(index.getId()),
// SORT_TYPE
ValueInteger.get(idxCol.sortType),
// CONSTRAINT_NAME
constraintName,
// INDEX_CLASS
indexClass
);
}
}
}
break;
}
case TABLE_TYPES: {
add(session, rows, TableType.TABLE.toString());
add(session, rows, TableType.TABLE_LINK.toString());
add(session, rows, TableType.SYSTEM_TABLE.toString());
add(session, rows, TableType.VIEW.toString());
add(session, rows, TableType.EXTERNAL_TABLE_ENGINE.toString());
break;
}
case TYPE_INFO: {
for (int i = 1, l = Value.TYPE_COUNT; i < l; i++) {
DataType t = DataType.getDataType(i);
add(session,
rows,
// TYPE_NAME
Value.getTypeName(t.type),
// DATA_TYPE
ValueInteger.get(t.sqlType),
// PRECISION
ValueInteger.get(MathUtils.convertLongToInt(t.maxPrecision)),
// PREFIX
t.prefix,
// SUFFIX
t.suffix,
// PARAMS
t.params,
// AUTO_INCREMENT
ValueBoolean.FALSE,
// MINIMUM_SCALE
ValueSmallint.get(MathUtils.convertIntToShort(t.minScale)),
// MAXIMUM_SCALE
ValueSmallint.get(MathUtils.convertIntToShort(t.maxScale)),
// RADIX
DataType.isNumericType(i) ? ValueInteger.get(10) : null,
// POS
ValueInteger.get(t.type),
// CASE_SENSITIVE
ValueBoolean.get(t.caseSensitive),
// NULLABLE
ValueSmallint.get((short) DatabaseMetaData.typeNullable),
// SEARCHABLE
ValueSmallint.get((short) DatabaseMetaData.typeSearchable)
);
}
break;
}
case CATALOGS: {
add(session, rows, catalog);
break;
}
case SETTINGS: {
for (Setting s : database.getAllSettings()) {
String value = s.getStringValue();
if (value == null) {
value = Integer.toString(s.getIntValue());
}
add(session,
rows,
identifier(s.getName()), value
);
}
add(session, rows, "info.BUILD_ID", "" + Constants.BUILD_ID);
add(session, rows, "info.VERSION_MAJOR", "" + Constants.VERSION_MAJOR);
add(session, rows, "info.VERSION_MINOR", "" + Constants.VERSION_MINOR);
add(session, rows, "info.VERSION", Constants.FULL_VERSION);
if (admin) {
String[] settings = {
"java.runtime.version", "java.vm.name",
"java.vendor", "os.name", "os.arch", "os.version",
"sun.os.patch.level", "file.separator",
"path.separator", "line.separator", "user.country",
"user.language", "user.variant", "file.encoding" };
for (String s : settings) {
add(session, rows, "property." + s, Utils.getProperty(s, ""));
}
}
add(session, rows, "DEFAULT_NULL_ORDERING", database.getDefaultNullOrdering().name());
add(session, rows, "EXCLUSIVE", database.getExclusiveSession() == null ?
"FALSE" : "TRUE");
add(session, rows, "MODE", database.getMode().getName());
add(session, rows, "QUERY_TIMEOUT", Integer.toString(session.getQueryTimeout()));
add(session, rows, "TIME ZONE", session.currentTimeZone().getId());
add(session, rows, "TRUNCATE_LARGE_LENGTH", session.isTruncateLargeLength() ? "TRUE" : "FALSE");
add(session, rows, "VARIABLE_BINARY", session.isVariableBinary() ? "TRUE" : "FALSE");
add(session, rows, "OLD_INFORMATION_SCHEMA", session.isOldInformationSchema() ? "TRUE" : "FALSE");
BitSet nonKeywords = session.getNonKeywords();
if (nonKeywords != null) {
add(session, rows, "NON_KEYWORDS", ParserBase.formatNonKeywords(nonKeywords));
}
add(session, rows, "RETENTION_TIME", Integer.toString(database.getRetentionTime()));
// database settings
for (Map.Entry entry : database.getSettings().getSortedSettings()) {
add(session, rows, entry.getKey(), entry.getValue());
}
database.getStore().getMvStore().populateInfo((name, value) -> add(session, rows, name, value));
break;
}
case HELP: {
String resource = "/org/h2/res/help.csv";
try {
final byte[] data = Utils.getResource(resource);
final Reader reader = new InputStreamReader(new ByteArrayInputStream(data), StandardCharsets.UTF_8);
final Csv csv = new Csv();
csv.setLineCommentCharacter('#');
final ResultSet rs = csv.read(reader, null);
final int columnCount = rs.getMetaData().getColumnCount() - 1;
final String[] values = new String[5];
for (int i = 0; rs.next(); i++) {
for (int j = 0; j < columnCount; j++) {
String s = rs.getString(1 + j);
switch (j) {
case 2: // SYNTAX column
// Strip out the special annotations we use to help build
// the railroad/BNF diagrams
s = Help.stripAnnotationsFromSyntax(s);
break;
case 3: // TEXT column
s = Help.processHelpText(s);
}
values[j] = s.trim();
}
add(session,
rows,
// ID
ValueInteger.get(i),
// SECTION
values[0],
// TOPIC
values[1],
// SYNTAX
values[2],
// TEXT
values[3]
);
}
} catch (Exception e) {
throw DbException.convert(e);
}
break;
}
case SEQUENCES: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.SEQUENCE)) {
Sequence s = (Sequence) obj;
TypeInfo dataType = s.getDataType();
String dataTypeName = Value.getTypeName(dataType.getValueType());
ValueInteger declaredScale = ValueInteger.get(dataType.getScale());
add(session,
rows,
// SEQUENCE_CATALOG
catalog,
// SEQUENCE_SCHEMA
s.getSchema().getName(),
// SEQUENCE_NAME
s.getName(),
// DATA_TYPE
dataTypeName,
// NUMERIC_PRECISION
ValueInteger.get(s.getEffectivePrecision()),
// NUMERIC_PRECISION_RADIX
ValueInteger.get(10),
// NUMERIC_SCALE
declaredScale,
// START_VALUE
ValueBigint.get(s.getStartValue()),
// MINIMUM_VALUE
ValueBigint.get(s.getMinValue()),
// MAXIMUM_VALUE
ValueBigint.get(s.getMaxValue()),
// INCREMENT
ValueBigint.get(s.getIncrement()),
// CYCLE_OPTION
s.getCycle().isCycle() ? "YES" : "NO",
// DECLARED_DATA_TYPE
dataTypeName,
// DECLARED_NUMERIC_PRECISION
ValueInteger.get((int) dataType.getPrecision()),
// DECLARED_NUMERIC_SCALE
declaredScale,
// CURRENT_VALUE
ValueBigint.get(s.getCurrentValue()),
// IS_GENERATED
ValueBoolean.get(s.getBelongsToTable()),
// REMARKS
replaceNullWithEmpty(s.getComment()),
// CACHE
ValueBigint.get(s.getCacheSize()),
// ID
ValueInteger.get(s.getId()),
// MIN_VALUE
ValueBigint.get(s.getMinValue()),
// MAX_VALUE
ValueBigint.get(s.getMaxValue()),
// IS_CYCLE
ValueBoolean.get(s.getCycle().isCycle())
);
}
break;
}
case USERS: {
for (RightOwner rightOwner : database.getAllUsersAndRoles()) {
if (rightOwner instanceof User) {
User u = (User) rightOwner;
if (admin || session.getUser() == u) {
add(session,
rows,
// NAME
identifier(u.getName()),
// ADMIN
String.valueOf(u.isAdmin()),
// REMARKS
replaceNullWithEmpty(u.getComment()),
// ID
ValueInteger.get(u.getId())
);
}
}
}
break;
}
case ROLES: {
for (RightOwner rightOwner : database.getAllUsersAndRoles()) {
if (rightOwner instanceof Role) {
Role r = (Role) rightOwner;
if (admin || session.getUser().isRoleGranted(r)) {
add(session,
rows,
// NAME
identifier(r.getName()),
// REMARKS
replaceNullWithEmpty(r.getComment()),
// ID
ValueInteger.get(r.getId())
);
}
}
}
break;
}
case RIGHTS: {
if (admin) {
for (Right r : database.getAllRights()) {
Role role = r.getGrantedRole();
DbObject grantee = r.getGrantee();
String rightType = grantee.getType() == DbObject.USER ? "USER" : "ROLE";
if (role == null) {
DbObject object = r.getGrantedObject();
Schema schema = null;
Table table = null;
if (object != null) {
if (object instanceof Schema) {
schema = (Schema) object;
} else if (object instanceof Table) {
table = (Table) object;
schema = table.getSchema();
}
}
String tableName = (table != null) ? table.getName() : "";
String schemaName = (schema != null) ? schema.getName() : "";
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
add(session,
rows,
// GRANTEE
identifier(grantee.getName()),
// GRANTEETYPE
rightType,
// GRANTEDROLE
"",
// RIGHTS
r.getRights(),
// TABLE_SCHEMA
schemaName,
// TABLE_NAME
tableName,
// ID
ValueInteger.get(r.getId())
);
} else {
add(session,
rows,
// GRANTEE
identifier(grantee.getName()),
// GRANTEETYPE
rightType,
// GRANTEDROLE
identifier(role.getName()),
// RIGHTS
"",
// TABLE_SCHEMA
"",
// TABLE_NAME
"",
// ID
ValueInteger.get(r.getId())
);
}
}
}
break;
}
case FUNCTION_ALIASES:
for (Schema schema : database.getAllSchemas()) {
for (UserDefinedFunction userDefinedFunction : schema.getAllFunctionsAndAggregates()) {
if (userDefinedFunction instanceof FunctionAlias) {
FunctionAlias alias = (FunctionAlias) userDefinedFunction;
JavaMethod[] methods;
try {
methods = alias.getJavaMethods();
} catch (DbException e) {
continue;
}
for (FunctionAlias.JavaMethod method : methods) {
TypeInfo typeInfo = method.getDataType();
if (typeInfo == null) {
typeInfo = TypeInfo.TYPE_NULL;
}
add(session,
rows,
// ALIAS_CATALOG
catalog,
// ALIAS_SCHEMA
alias.getSchema().getName(),
// ALIAS_NAME
alias.getName(),
// JAVA_CLASS
alias.getJavaClassName(),
// JAVA_METHOD
alias.getJavaMethodName(),
// DATA_TYPE
ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)),
// TYPE_NAME
typeInfo.getDeclaredTypeName(),
// COLUMN_COUNT
ValueInteger.get(method.getParameterCount()),
// RETURNS_RESULT
ValueSmallint.get(typeInfo.getValueType() == Value.NULL
? (short) DatabaseMetaData.procedureNoResult
: (short) DatabaseMetaData.procedureReturnsResult),
// REMARKS
replaceNullWithEmpty(alias.getComment()),
// ID
ValueInteger.get(alias.getId()),
// SOURCE
alias.getSource()
// when adding more columns, see also below
);
}
} else {
add(session,
rows,
// ALIAS_CATALOG
catalog,
// ALIAS_SCHEMA
database.getMainSchema().getName(),
// ALIAS_NAME
userDefinedFunction.getName(),
// JAVA_CLASS
userDefinedFunction.getJavaClassName(),
// JAVA_METHOD
"",
// DATA_TYPE
ValueInteger.get(Types.NULL),
// TYPE_NAME
"NULL",
// COLUMN_COUNT
ValueInteger.get(1),
// RETURNS_RESULT
ValueSmallint.get((short) DatabaseMetaData.procedureReturnsResult),
// REMARKS
replaceNullWithEmpty(userDefinedFunction.getComment()),
// ID
ValueInteger.get(userDefinedFunction.getId()),
// SOURCE
""
// when adding more columns, see also below
);
}
}
}
break;
case FUNCTION_COLUMNS:
for (Schema schema : database.getAllSchemas()) {
for (UserDefinedFunction userDefinedFunction : schema.getAllFunctionsAndAggregates()) {
if (userDefinedFunction instanceof FunctionAlias) {
FunctionAlias alias = (FunctionAlias) userDefinedFunction;
JavaMethod[] methods;
try {
methods = alias.getJavaMethods();
} catch (DbException e) {
continue;
}
for (FunctionAlias.JavaMethod method : methods) {
// Add return column index 0
TypeInfo typeInfo = method.getDataType();
if (typeInfo != null && typeInfo.getValueType() != Value.NULL) {
DataType dt = DataType.getDataType(typeInfo.getValueType());
add(session,
rows,
// ALIAS_CATALOG
catalog,
// ALIAS_SCHEMA
alias.getSchema().getName(),
// ALIAS_NAME
alias.getName(),
// JAVA_CLASS
alias.getJavaClassName(),
// JAVA_METHOD
alias.getJavaMethodName(),
// COLUMN_COUNT
ValueInteger.get(method.getParameterCount()),
// POS
ValueInteger.get(0),
// COLUMN_NAME
"P0",
// DATA_TYPE
ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)),
// TYPE_NAME
typeInfo.getDeclaredTypeName(),
// PRECISION
ValueInteger.get(MathUtils.convertLongToInt(dt.defaultPrecision)),
// SCALE
ValueSmallint.get(MathUtils.convertIntToShort(dt.defaultScale)),
// RADIX
ValueSmallint.get((short) 10),
// NULLABLE
ValueSmallint.get((short) DatabaseMetaData.columnNullableUnknown),
// COLUMN_TYPE
ValueSmallint.get((short) DatabaseMetaData.procedureColumnReturn),
// REMARKS
"",
// COLUMN_DEFAULT
null
);
}
Class>[] columnList = method.getColumnClasses();
for (int k = 0; k < columnList.length; k++) {
if (method.hasConnectionParam() && k == 0) {
continue;
}
Class> clazz = columnList[k];
TypeInfo columnTypeInfo = ValueToObjectConverter2.classToType(clazz);
DataType dt = DataType.getDataType(columnTypeInfo.getValueType());
add(session,
rows,
// ALIAS_CATALOG
catalog,
// ALIAS_SCHEMA
alias.getSchema().getName(),
// ALIAS_NAME
alias.getName(),
// JAVA_CLASS
alias.getJavaClassName(),
// JAVA_METHOD
alias.getJavaMethodName(),
// COLUMN_COUNT
ValueInteger.get(method.getParameterCount()),
// POS
ValueInteger.get(k + (method.hasConnectionParam() ? 0 : 1)),
// COLUMN_NAME
"P" + (k + 1),
// DATA_TYPE
ValueInteger.get(DataType.convertTypeToSQLType(columnTypeInfo)),
// TYPE_NAME
columnTypeInfo.getDeclaredTypeName(),
// PRECISION
ValueInteger.get(MathUtils.convertLongToInt(dt.defaultPrecision)),
// SCALE
ValueSmallint.get(MathUtils.convertIntToShort(dt.defaultScale)),
// RADIX
ValueSmallint.get((short) 10),
// NULLABLE
ValueSmallint.get(clazz.isPrimitive()
? (short) DatabaseMetaData.columnNoNulls
: (short) DatabaseMetaData.columnNullable),
// COLUMN_TYPE
ValueSmallint.get((short) DatabaseMetaData.procedureColumnIn),
// REMARKS
"",
// COLUMN_DEFAULT
null
);
}
}
}
}
}
break;
case SCHEMATA: {
String collation = database.getCompareMode().getName();
for (Schema schema : database.getAllSchemas()) {
add(session,
rows,
// CATALOG_NAME
catalog,
// SCHEMA_NAME
schema.getName(),
// SCHEMA_OWNER
identifier(schema.getOwner().getName()),
// DEFAULT_CHARACTER_SET_NAME
CHARACTER_SET_NAME,
// DEFAULT_COLLATION_NAME
collation,
// IS_DEFAULT
ValueBoolean.get(schema.getId() == Constants.MAIN_SCHEMA_ID),
// REMARKS
replaceNullWithEmpty(schema.getComment()),
// ID
ValueInteger.get(schema.getId())
);
}
break;
}
case TABLE_PRIVILEGES: {
for (Right r : database.getAllRights()) {
DbObject object = r.getGrantedObject();
if (!(object instanceof Table)) {
continue;
}
Table table = (Table) object;
if (hideTable(table, session)) {
continue;
}
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
addPrivileges(session, rows, r.getGrantee(), catalog, table, null, r.getRightMask());
}
break;
}
case COLUMN_PRIVILEGES: {
for (Right r : database.getAllRights()) {
DbObject object = r.getGrantedObject();
if (!(object instanceof Table)) {
continue;
}
Table table = (Table) object;
if (hideTable(table, session)) {
continue;
}
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
DbObject grantee = r.getGrantee();
int mask = r.getRightMask();
for (Column column : table.getColumns()) {
addPrivileges(session, rows, grantee, catalog, table, column.getName(), mask);
}
}
break;
}
case COLLATIONS: {
for (Locale l : CompareMode.getCollationLocales(false)) {
add(session,
rows,
// NAME
CompareMode.getName(l), // KEY
l.toString()
);
}
break;
}
case VIEWS: {
for (Table table : getAllTables(session)) {
if (table.getTableType() != TableType.VIEW) {
continue;
}
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
TableView view = (TableView) table;
add(session,
rows,
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
tableName,
// VIEW_DEFINITION
table.getCreateSQL(),
// CHECK_OPTION
"NONE",
// IS_UPDATABLE
"NO",
// STATUS
view.isInvalid() ? "INVALID" : "VALID",
// REMARKS
replaceNullWithEmpty(view.getComment()),
// ID
ValueInteger.get(view.getId())
);
}
break;
}
case IN_DOUBT: {
ArrayList prepared = database.getInDoubtTransactions();
if (prepared != null && admin) {
for (InDoubtTransaction prep : prepared) {
add(session,
rows,
// TRANSACTION
prep.getTransactionName(), // STATE
prep.getStateDescription()
);
}
}
break;
}
case CROSS_REFERENCES: {
for (SchemaObject obj : getAllSchemaObjects(
DbObject.CONSTRAINT)) {
Constraint constraint = (Constraint) obj;
if (constraint.getConstraintType() != Constraint.Type.REFERENTIAL) {
continue;
}
ConstraintReferential ref = (ConstraintReferential) constraint;
IndexColumn[] cols = ref.getColumns();
IndexColumn[] refCols = ref.getRefColumns();
Table tab = ref.getTable();
Table refTab = ref.getRefTable();
String tableName = refTab.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
ValueSmallint update = ValueSmallint.get(getRefAction(ref.getUpdateAction()));
ValueSmallint delete = ValueSmallint.get(getRefAction(ref.getDeleteAction()));
for (int j = 0; j < cols.length; j++) {
add(session,
rows,
// PKTABLE_CATALOG
catalog,
// PKTABLE_SCHEMA
refTab.getSchema().getName(),
// PKTABLE_NAME
refTab.getName(),
// PKCOLUMN_NAME
refCols[j].column.getName(),
// FKTABLE_CATALOG
catalog,
// FKTABLE_SCHEMA
tab.getSchema().getName(),
// FKTABLE_NAME
tab.getName(),
// FKCOLUMN_NAME
cols[j].column.getName(),
// ORDINAL_POSITION
ValueSmallint.get((short) (j + 1)),
// UPDATE_RULE
update,
// DELETE_RULE
delete,
// FK_NAME
ref.getName(),
// PK_NAME
ref.getReferencedConstraint().getName(),
// DEFERRABILITY
ValueSmallint.get((short) DatabaseMetaData.importedKeyNotDeferrable)
);
}
}
break;
}
case CONSTRAINTS: {
for (SchemaObject obj : getAllSchemaObjects(
DbObject.CONSTRAINT)) {
Constraint constraint = (Constraint) obj;
Constraint.Type constraintType = constraint.getConstraintType();
String checkExpression = null;
IndexColumn[] indexColumns = null;
Table table = constraint.getTable();
if (hideTable(table, session)) {
continue;
}
Index index = constraint.getIndex();
String uniqueIndexName = null;
if (index != null) {
uniqueIndexName = index.getName();
}
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
if (constraintType == Constraint.Type.CHECK) {
checkExpression = constraint.getExpression().getSQL(HasSQL.DEFAULT_SQL_FLAGS);
} else if (constraintType == Constraint.Type.UNIQUE ||
constraintType == Constraint.Type.PRIMARY_KEY) {
indexColumns = ((ConstraintUnique) constraint).getColumns();
} else if (constraintType == Constraint.Type.REFERENTIAL) {
indexColumns = ((ConstraintReferential) constraint).getColumns();
}
String columnList = null;
if (indexColumns != null) {
StringBuilder builder = new StringBuilder();
for (int i = 0, length = indexColumns.length; i < length; i++) {
if (i > 0) {
builder.append(',');
}
builder.append(indexColumns[i].column.getName());
}
columnList = builder.toString();
}
add(session,
rows,
// CONSTRAINT_CATALOG
catalog,
// CONSTRAINT_SCHEMA
constraint.getSchema().getName(),
// CONSTRAINT_NAME
constraint.getName(),
// CONSTRAINT_TYPE
constraintType == Constraint.Type.PRIMARY_KEY ?
constraintType.getSqlName() : constraintType.name(),
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
tableName,
// UNIQUE_INDEX_NAME
uniqueIndexName,
// CHECK_EXPRESSION
checkExpression,
// COLUMN_LIST
columnList,
// REMARKS
replaceNullWithEmpty(constraint.getComment()),
// SQL
constraint.getCreateSQL(),
// ID
ValueInteger.get(constraint.getId())
);
}
break;
}
case CONSTANTS: {
for (SchemaObject obj : getAllSchemaObjects(
DbObject.CONSTANT)) {
Constant constant = (Constant) obj;
ValueExpression expr = constant.getValue();
add(session,
rows,
// CONSTANT_CATALOG
catalog,
// CONSTANT_SCHEMA
constant.getSchema().getName(),
// CONSTANT_NAME
constant.getName(),
// DATA_TYPE
ValueInteger.get(DataType.convertTypeToSQLType(expr.getType())),
// REMARKS
replaceNullWithEmpty(constant.getComment()),
// SQL
expr.getSQL(DEFAULT_SQL_FLAGS),
// ID
ValueInteger.get(constant.getId())
);
}
break;
}
case DOMAINS: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.DOMAIN)) {
Domain domain = (Domain) obj;
Domain parentDomain = domain.getDomain();
TypeInfo typeInfo = domain.getDataType();
add(session,
rows,
// DOMAIN_CATALOG
catalog,
// DOMAIN_SCHEMA
domain.getSchema().getName(),
// DOMAIN_NAME
domain.getName(),
// DOMAIN_DEFAULT
domain.getDefaultSQL(),
// DOMAIN_ON_UPDATE
domain.getOnUpdateSQL(),
// DATA_TYPE
ValueInteger.get(DataType.convertTypeToSQLType(typeInfo)),
// PRECISION
ValueInteger.get(MathUtils.convertLongToInt(typeInfo.getPrecision())),
// SCALE
ValueInteger.get(typeInfo.getScale()),
// TYPE_NAME
typeInfo.getDeclaredTypeName(),
// PARENT_DOMAIN_CATALOG
parentDomain != null ? catalog : null,
// PARENT_DOMAIN_SCHEMA
parentDomain != null ? parentDomain.getSchema().getName() : null,
// PARENT_DOMAIN_NAME
parentDomain != null ? parentDomain.getName() : null,
// SELECTIVITY INT
ValueInteger.get(Constants.SELECTIVITY_DEFAULT),
// REMARKS
replaceNullWithEmpty(domain.getComment()),
// SQL
domain.getCreateSQL(),
// ID
ValueInteger.get(domain.getId()),
// COLUMN_DEFAULT
domain.getDefaultSQL(),
// IS_NULLABLE
"YES",
// CHECK_CONSTRAINT
null
);
}
break;
}
case TRIGGERS: {
for (SchemaObject obj : getAllSchemaObjects(
DbObject.TRIGGER)) {
TriggerObject trigger = (TriggerObject) obj;
Table table = trigger.getTable();
add(session,
rows,
// TRIGGER_CATALOG
catalog,
// TRIGGER_SCHEMA
trigger.getSchema().getName(),
// TRIGGER_NAME
trigger.getName(),
// TRIGGER_TYPE
trigger.getTypeNameList(new StringBuilder()).toString(),
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
table.getName(),
// BEFORE
ValueBoolean.get(trigger.isBefore()),
// JAVA_CLASS
trigger.getTriggerClassName(),
// QUEUE_SIZE
ValueInteger.get(trigger.getQueueSize()),
// NO_WAIT
ValueBoolean.get(trigger.isNoWait()),
// REMARKS
replaceNullWithEmpty(trigger.getComment()),
// SQL
trigger.getCreateSQL(),
// ID
ValueInteger.get(trigger.getId())
);
}
break;
}
case SESSIONS: {
for (SessionLocal s : database.getSessions(false)) {
if (admin || s == session) {
NetworkConnectionInfo networkConnectionInfo = s.getNetworkConnectionInfo();
Command command = s.getCurrentCommand();
int blockingSessionId = s.getBlockingSessionId();
add(session,
rows,
// ID
ValueInteger.get(s.getId()),
// USER_NAME
s.getUser().getName(),
// SERVER
networkConnectionInfo == null ? null : networkConnectionInfo.getServer(),
// CLIENT_ADDR
networkConnectionInfo == null ? null : networkConnectionInfo.getClient(),
// CLIENT_INFO
networkConnectionInfo == null ? null : networkConnectionInfo.getClientInfo(),
// SESSION_START
s.getSessionStart(),
// ISOLATION_LEVEL
s.getIsolationLevel().getSQL(),
// STATEMENT
command == null ? null : command.toString(),
// STATEMENT_START
command == null ? null : s.getCommandStartOrEnd(),
// CONTAINS_UNCOMMITTED
ValueBoolean.get(s.hasPendingTransaction()),
// STATE
String.valueOf(s.getState()),
// BLOCKER_ID
blockingSessionId == 0 ? null : ValueInteger.get(blockingSessionId),
// SLEEP_SINCE
s.getState() == State.SLEEP ? s.getCommandStartOrEnd() : null
);
}
}
break;
}
case LOCKS: {
for (SessionLocal s : database.getSessions(false)) {
if (admin || s == session) {
for (Table table : s.getLocks()) {
add(session,
rows,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
table.getName(),
// SESSION_ID
ValueInteger.get(s.getId()),
// LOCK_TYPE
table.isLockedExclusivelyBy(s) ? "WRITE" : "READ"
);
}
}
}
break;
}
case SESSION_STATE: {
for (String name : session.getVariableNames()) {
Value v = session.getVariable(name);
StringBuilder builder = new StringBuilder().append("SET @").append(name).append(' ');
v.getSQL(builder, DEFAULT_SQL_FLAGS);
add(session,
rows,
// KEY
"@" + name,
// SQL
builder.toString()
);
}
for (Table table : session.getLocalTempTables()) {
add(session,
rows,
// KEY
"TABLE " + table.getName(),
// SQL
table.getCreateSQL()
);
}
String[] path = session.getSchemaSearchPath();
if (path != null && path.length > 0) {
StringBuilder builder = new StringBuilder("SET SCHEMA_SEARCH_PATH ");
for (int i = 0, l = path.length; i < l; i++) {
if (i > 0) {
builder.append(", ");
}
StringUtils.quoteIdentifier(builder, path[i]);
}
add(session,
rows,
// KEY
"SCHEMA_SEARCH_PATH",
// SQL
builder.toString()
);
}
String schema = session.getCurrentSchemaName();
if (schema != null) {
add(session,
rows,
// KEY
"SCHEMA",
// SQL
StringUtils.quoteIdentifier(new StringBuilder("SET SCHEMA "), schema).toString()
);
}
TimeZoneProvider currentTimeZone = session.currentTimeZone();
if (!currentTimeZone.equals(DateTimeUtils.getTimeZone())) {
add(session,
rows,
// KEY
"TIME ZONE",
// SQL
StringUtils.quoteStringSQL(new StringBuilder("SET TIME ZONE "), currentTimeZone.getId())
.toString()
);
}
break;
}
case QUERY_STATISTICS: {
QueryStatisticsData control = database.getQueryStatisticsData();
if (control != null) {
for (QueryStatisticsData.QueryEntry entry : control.getQueries()) {
add(session,
rows,
// SQL_STATEMENT
entry.sqlStatement,
// EXECUTION_COUNT
ValueInteger.get(entry.count),
// MIN_EXECUTION_TIME
ValueDouble.get(entry.executionTimeMinNanos / 1_000_000d),
// MAX_EXECUTION_TIME
ValueDouble.get(entry.executionTimeMaxNanos / 1_000_000d),
// CUMULATIVE_EXECUTION_TIME
ValueDouble.get(entry.executionTimeCumulativeNanos / 1_000_000d),
// AVERAGE_EXECUTION_TIME
ValueDouble.get(entry.executionTimeMeanNanos / 1_000_000d),
// STD_DEV_EXECUTION_TIME
ValueDouble.get(entry.getExecutionTimeStandardDeviation() / 1_000_000d),
// MIN_ROW_COUNT
ValueBigint.get(entry.rowCountMin),
// MAX_ROW_COUNT
ValueBigint.get(entry.rowCountMax),
// CUMULATIVE_ROW_COUNT
ValueBigint.get(entry.rowCountCumulative),
// AVERAGE_ROW_COUNT
ValueDouble.get(entry.rowCountMean),
// STD_DEV_ROW_COUNT
ValueDouble.get(entry.getRowCountStandardDeviation())
);
}
}
break;
}
case SYNONYMS: {
for (TableSynonym synonym : database.getAllSynonyms()) {
add(session,
rows,
// SYNONYM_CATALOG
catalog,
// SYNONYM_SCHEMA
synonym.getSchema().getName(),
// SYNONYM_NAME
synonym.getName(),
// SYNONYM_FOR
synonym.getSynonymForName(),
// SYNONYM_FOR_SCHEMA
synonym.getSynonymForSchema().getName(),
// TYPE NAME
"SYNONYM",
// STATUS
"VALID",
// REMARKS
replaceNullWithEmpty(synonym.getComment()),
// ID
ValueInteger.get(synonym.getId())
);
}
break;
}
case TABLE_CONSTRAINTS: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
Constraint constraint = (Constraint) obj;
Constraint.Type constraintType = constraint.getConstraintType();
if (constraintType == Constraint.Type.DOMAIN) {
continue;
}
Table table = constraint.getTable();
if (hideTable(table, session)) {
continue;
}
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
add(session,
rows,
// CONSTRAINT_CATALOG
catalog,
// CONSTRAINT_SCHEMA
constraint.getSchema().getName(),
// CONSTRAINT_NAME
constraint.getName(),
// CONSTRAINT_TYPE
constraintType.getSqlName(),
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
tableName,
// IS_DEFERRABLE
"NO",
// INITIALLY_DEFERRED
"NO",
// REMARKS
replaceNullWithEmpty(constraint.getComment()),
// SQL
constraint.getCreateSQL(),
// ID
ValueInteger.get(constraint.getId())
);
}
break;
}
case DOMAIN_CONSTRAINTS: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
if (((Constraint) obj).getConstraintType() != Constraint.Type.DOMAIN) {
continue;
}
ConstraintDomain constraint = (ConstraintDomain) obj;
Domain domain = constraint.getDomain();
add(session,
rows,
// CONSTRAINT_CATALOG
catalog,
// CONSTRAINT_SCHEMA
constraint.getSchema().getName(),
// CONSTRAINT_NAME
constraint.getName(),
// DOMAIN_CATALOG
catalog,
// DOMAIN_SCHEMA
domain.getSchema().getName(),
// DOMAIN_NAME
domain.getName(),
// IS_DEFERRABLE
"NO",
// INITIALLY_DEFERRED
"NO",
// REMARKS
replaceNullWithEmpty(constraint.getComment()),
// SQL
constraint.getCreateSQL(),
// ID
ValueInteger.get(constraint.getId())
);
}
break;
}
case KEY_COLUMN_USAGE: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
Constraint constraint = (Constraint) obj;
Constraint.Type constraintType = constraint.getConstraintType();
IndexColumn[] indexColumns = null;
if (constraintType == Constraint.Type.UNIQUE || constraintType == Constraint.Type.PRIMARY_KEY) {
indexColumns = ((ConstraintUnique) constraint).getColumns();
} else if (constraintType == Constraint.Type.REFERENTIAL) {
indexColumns = ((ConstraintReferential) constraint).getColumns();
}
if (indexColumns == null) {
continue;
}
Table table = constraint.getTable();
if (hideTable(table, session)) {
continue;
}
String tableName = table.getName();
if (!checkIndex(session, tableName, indexFrom, indexTo)) {
continue;
}
ConstraintUnique referenced;
if (constraintType == Constraint.Type.REFERENTIAL) {
referenced = constraint.getReferencedConstraint();
} else {
referenced = null;
}
Index index = constraint.getIndex();
for (int i = 0; i < indexColumns.length; i++) {
IndexColumn indexColumn = indexColumns[i];
ValueInteger ordinalPosition = ValueInteger.get(i + 1);
ValueInteger positionInUniqueConstraint = null;
if (referenced != null) {
Column c = ((ConstraintReferential) constraint).getRefColumns()[i].column;
IndexColumn[] refColumns = referenced.getColumns();
for (int j = 0; j < refColumns.length; j++) {
if (refColumns[j].column.equals(c)) {
positionInUniqueConstraint = ValueInteger.get(j + 1);
break;
}
}
}
add(session,
rows,
// CONSTRAINT_CATALOG
catalog,
// CONSTRAINT_SCHEMA
constraint.getSchema().getName(),
// CONSTRAINT_NAME
constraint.getName(),
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
tableName,
// COLUMN_NAME
indexColumn.columnName,
// ORDINAL_POSITION
ordinalPosition,
// POSITION_IN_UNIQUE_CONSTRAINT
positionInUniqueConstraint,
// INDEX_CATALOG
index != null ? catalog : null,
// INDEX_SCHEMA
index != null ? index.getSchema().getName() : null,
// INDEX_NAME
index != null ? index.getName() : null
);
}
}
break;
}
case REFERENTIAL_CONSTRAINTS: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
if (((Constraint) obj).getConstraintType() != Constraint.Type.REFERENTIAL) {
continue;
}
ConstraintReferential constraint = (ConstraintReferential) obj;
Table table = constraint.getTable();
if (hideTable(table, session)) {
continue;
}
ConstraintUnique unique = constraint.getReferencedConstraint();
add(session,
rows,
// CONSTRAINT_CATALOG
catalog,
// CONSTRAINT_SCHEMA
constraint.getSchema().getName(),
// CONSTRAINT_NAME
constraint.getName(),
// UNIQUE_CONSTRAINT_CATALOG
catalog,
// UNIQUE_CONSTRAINT_SCHEMA
unique.getSchema().getName(),
// UNIQUE_CONSTRAINT_NAME
unique.getName(),
// MATCH_OPTION
"NONE",
// UPDATE_RULE
constraint.getUpdateAction().getSqlName(),
// DELETE_RULE
constraint.getDeleteAction().getSqlName()
);
}
break;
}
case CHECK_CONSTRAINTS: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
Constraint constraint = (Constraint) obj;
Type constraintType = constraint.getConstraintType();
if (constraintType == Constraint.Type.CHECK) {
ConstraintCheck check = (ConstraintCheck) obj;
Table table = check.getTable();
if (hideTable(table, session)) {
continue;
}
} else if (constraintType != Constraint.Type.DOMAIN) {
continue;
}
add(session,
rows,
// CONSTRAINT_CATALOG
catalog,
// CONSTRAINT_SCHEMA
obj.getSchema().getName(),
// CONSTRAINT_NAME
obj.getName(),
// CHECK_CLAUSE
constraint.getExpression().getSQL(DEFAULT_SQL_FLAGS, Expression.WITHOUT_PARENTHESES)
);
}
break;
}
case CONSTRAINT_COLUMN_USAGE: {
for (SchemaObject obj : getAllSchemaObjects(DbObject.CONSTRAINT)) {
Constraint constraint = (Constraint) obj;
switch (constraint.getConstraintType()) {
case CHECK:
case DOMAIN: {
HashSet columns = new HashSet<>();
constraint.getExpression().isEverything(ExpressionVisitor.getColumnsVisitor(columns, null));
for (Column column: columns) {
Table table = column.getTable();
if (checkIndex(session, table.getName(), indexFrom, indexTo) && !hideTable(table, session)) {
addConstraintColumnUsage(session, rows, catalog, constraint, column);
}
}
break;
}
case REFERENTIAL: {
Table table = constraint.getRefTable();
if (checkIndex(session, table.getName(), indexFrom, indexTo) && !hideTable(table, session)) {
for (Column column : constraint.getReferencedColumns(table)) {
addConstraintColumnUsage(session, rows, catalog, constraint, column);
}
}
}
//$FALL-THROUGH$
case PRIMARY_KEY:
case UNIQUE: {
Table table = constraint.getTable();
if (checkIndex(session, table.getName(), indexFrom, indexTo) && !hideTable(table, session)) {
for (Column column : constraint.getReferencedColumns(table)) {
addConstraintColumnUsage(session, rows, catalog, constraint, column);
}
}
}
}
}
break;
}
default:
throw DbException.getInternalError("type=" + type);
}
return rows;
}
private static short getRefAction(ConstraintActionType action) {
switch (action) {
case CASCADE:
return DatabaseMetaData.importedKeyCascade;
case RESTRICT:
return DatabaseMetaData.importedKeyRestrict;
case SET_DEFAULT:
return DatabaseMetaData.importedKeySetDefault;
case SET_NULL:
return DatabaseMetaData.importedKeySetNull;
default:
throw DbException.getInternalError("action="+action);
}
}
private void addConstraintColumnUsage(SessionLocal session, ArrayList rows, String catalog,
Constraint constraint, Column column) {
Table table = column.getTable();
add(session,
rows,
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
table.getName(),
// COLUMN_NAME
column.getName(),
// CONSTRAINT_CATALOG
catalog,
// CONSTRAINT_SCHEMA
constraint.getSchema().getName(),
// CONSTRAINT_NAME
constraint.getName()
);
}
private void addPrivileges(SessionLocal session, ArrayList rows, DbObject grantee,
String catalog, Table table, String column, int rightMask) {
if ((rightMask & Right.SELECT) != 0) {
addPrivilege(session, rows, grantee, catalog, table, column, "SELECT");
}
if ((rightMask & Right.INSERT) != 0) {
addPrivilege(session, rows, grantee, catalog, table, column, "INSERT");
}
if ((rightMask & Right.UPDATE) != 0) {
addPrivilege(session, rows, grantee, catalog, table, column, "UPDATE");
}
if ((rightMask & Right.DELETE) != 0) {
addPrivilege(session, rows, grantee, catalog, table, column, "DELETE");
}
}
private void addPrivilege(SessionLocal session, ArrayList rows, DbObject grantee,
String catalog, Table table, String column, String right) {
String isGrantable = "NO";
if (grantee.getType() == DbObject.USER) {
User user = (User) grantee;
if (user.isAdmin()) {
// the right is grantable if the grantee is an admin
isGrantable = "YES";
}
}
if (column == null) {
add(session,
rows,
// GRANTOR
null,
// GRANTEE
identifier(grantee.getName()),
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
table.getName(),
// PRIVILEGE_TYPE
right,
// IS_GRANTABLE
isGrantable
);
} else {
add(session,
rows,
// GRANTOR
null,
// GRANTEE
identifier(grantee.getName()),
// TABLE_CATALOG
catalog,
// TABLE_SCHEMA
table.getSchema().getName(),
// TABLE_NAME
table.getName(),
// COLUMN_NAME
column,
// PRIVILEGE_TYPE
right,
// IS_GRANTABLE
isGrantable
);
}
}
private ArrayList getAllSchemaObjects(int type) {
ArrayList list = new ArrayList<>();
for (Schema schema : database.getAllSchemas()) {
schema.getAll(type, list);
}
return list;
}
/**
* Get all tables of this database, including local temporary tables for the
* session.
*
* @param session the session
* @return the array of tables
*/
private ArrayList getAllTables(SessionLocal session) {
ArrayList tables = new ArrayList<>();
for (Schema schema : database.getAllSchemas()) {
tables.addAll(schema.getAllTablesAndViews(session));
}
tables.addAll(session.getLocalTempTables());
return tables;
}
private ArrayList getTablesByName(SessionLocal session, String tableName) {
// we expect that at most one table matches, at least in most cases
ArrayList tables = new ArrayList<>(1);
for (Schema schema : database.getAllSchemas()) {
Table table = schema.getTableOrViewByName(session, tableName);
if (table != null) {
tables.add(table);
}
}
Table table = session.findLocalTempTable(tableName);
if (table != null) {
tables.add(table);
}
return tables;
}
@Override
public long getMaxDataModificationId() {
switch (type) {
case SETTINGS:
case SEQUENCES:
case IN_DOUBT:
case SESSIONS:
case LOCKS:
case SESSION_STATE:
return Long.MAX_VALUE;
}
return database.getModificationDataId();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy