Mercurial > hg > monetdb-java
changeset 367:1d7f8e969c47
Undo accidental checkin of Work In Progress.
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Wed, 16 Sep 2020 19:14:39 +0200 (2020-09-16) |
parents | 83bfade6333e |
children | af6db116238d |
files | src/main/java/nl/cwi/monetdb/client/JdbcClient.java |
diffstat | 1 files changed, 1 insertions(+), 1040 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/client/JdbcClient.java +++ b/src/main/java/nl/cwi/monetdb/client/JdbcClient.java @@ -43,7 +43,7 @@ import java.util.List; * of JDBC only. * * @author Fabian Groffen, Martin van Dinther - * @version 1.5 + * @version 1.4 */ public final class JdbcClient { @@ -781,8 +781,6 @@ public final class JdbcClient { if (tbl != null) tbl.close(); } - } else if (command.equals("\\check_system_catalog_integrity")) { - MDBvalidator.check_system_catalog_integrity(con); } else if (command.startsWith("\\l") || command.startsWith("\\i")) { String object = command.substring(2).trim(); if (scolonterm && object.endsWith(";")) @@ -1306,1040 +1304,3 @@ final class Table { } } -/** - * MonetDB Data Integrity Validator program (MDBvalidator) can - * a) check system tables data integrity (in system schemas: sys, tmp, json, profiler, and possibly more depending on MonetDB version) - * this includes violations of: - * primary key uniqueness - * primary key column(s) not null - * unique constraint uniqueness (alternate keys) - * foreign key referential integrity (match / partial) - * column not null - * column maximum length for char/varchar/clob/blob/json/url - * b) check user schema tables & columns data integrity based on available meta data from system tables/views - * column not null - * column maximum length for char/varchar/clob/blob/json/url - * TODO primary key uniqueness - * TODO primary key column(s) not null - * TODO unique constraint uniqueness (alternate keys) - * TODO foreign key referential integrity (match / partial) - * - * designed and created by Martin van Dinther - */ - -final class MDBvalidator { - private static final String prg = "MDBvalidator"; - private static Connection con; - private static int majorversion; - private static int minorversion; - - private static boolean verbose = false; // set it to true for tracing all generated SQL queries -// private static boolean use_log_table = false; // Not Yet Supported (and maybe not needed) - -// MDBvalidator() {} - - public static void main(String[] args) throws Exception { - System.out.println(prg + " started with " + args.length + " arguments." + (args.length == 0 ? " Using default JDBC URL !" : "")); - // parse input args: connection (JDBC_URL), check systbls (default) or user schema or user db - - String JDBC_URL = (args.length > 0) ? args[0] - : "jdbc:monetdb://localhost:50000/demo?user=monetdb&password=monetdb&so_timeout=14000"; // &treat_clob_as_varchar=true"; - if (!JDBC_URL.startsWith("jdbc:monetdb://")) { - System.out.println("ERROR: Invalid JDBC URL. It does not start with jdbc:monetdb:"); - return; - } - try { - // make connection to target server - con = java.sql.DriverManager.getConnection(JDBC_URL); - System.out.println(prg + " connected to MonetDB server"); - printExceptions(con.getWarnings()); - - check_system_catalog_integrity(con); - } catch (SQLException e) { - printExceptions(e); - } - - // free resources - if (con != null) { - try { con.close(); } catch (SQLException e) { /* ignore */ } - } - } - - static void check_system_catalog_integrity(Connection conn) { - long start_time = System.currentTimeMillis(); - try { - con = conn; - // retrieve server version numbers (major and minor). These are needed to filter out version specific validations - DatabaseMetaData dbmd = con.getMetaData(); - if (dbmd != null) { - majorversion = dbmd.getDatabaseMajorVersion(); - minorversion = dbmd.getDatabaseMinorVersion(); - System.out.println("MonetDB server version " + dbmd.getDatabaseProductVersion()); - // validate majorversion (should be 11) and minorversion (should be >= 19) (from Jul2015 (11.19.15)) - if (majorversion < 11 || (majorversion == 11 && minorversion < 19)) { - System.out.println("ERROR: this MonetDB server is too old for " + prg + ". Please upgrade server."); - con.close(); - return; - } - } - String cur_schema = con.getSchema(); - if (!"sys".equals(cur_schema)) - con.setSchema("sys"); - - verify("sys", null, sys_pkeys, sys_akeys, sys_fkeys, sys_notnull, true); - verify("tmp", null, tmp_pkeys, tmp_akeys, tmp_fkeys, tmp_notnull, true); - - // first determine if netcdf tables (sys.netcdf_files, sys.netcdf_dims, sys.netcdf_vars, sys.netcdf_vardim) exist in the db - if (false) { // ToDo built check for existance of the 5 netcdf tables in sys - verify("sys", "netcdf", netcdf_pkeys, netcdf_akeys, netcdf_fkeys, netcdf_notnull, false); - } - - // first determine if geom tables (sys.spatial_ref_sys) exist in the db - if (true) { // ToDo built check for existance of the 2 geom tables in sys - verify("sys", "geom", geom_pkeys, geom_akeys, geom_fkeys, geom_notnull, false); - } - } catch (SQLException e) { - printExceptions(e); - } - - long elapsed = System.currentTimeMillis() - start_time; - long secs = elapsed /1000; - System.out.println("Validation completed in " + secs + "s and " + (elapsed - (secs *1000)) + "ms"); - } - - private static void verify(String schema, String group, String[][] pkeys, String[][] akeys, String[][] fkeys, String[][] colnotnull, boolean checkmaxstr) { - boolean is_system_schema = ("sys".equals(schema) || "tmp".equals(schema)); - if (pkeys != null) - verifyUniqueness(schema, group, pkeys, "Primary Key uniqueness"); - if (pkeys != null) - verifyNotNull(schema, group, pkeys, "Primary Key Not Null"); - if (akeys != null) - verifyUniqueness(schema, group, akeys, "Alternate Key uniqueness"); - if (fkeys != null) - verifyFKs(schema, group, fkeys, "Foreign Key referential integrity"); - if (colnotnull != null) - verifyNotNull(schema, group, colnotnull, "Not Null"); - else - verifyNotNull(schema, is_system_schema, "Not Null"); - if (checkmaxstr) - verifyMaxCharStrLength(schema, is_system_schema, "Max Character Length"); -/* TODO - * col char/varchar/clob/blob/json/url minimum length (some columns may not be empty, so length >= 1) - * col with sequence (serial/bigserial/autoincrement) in range (0/1/min_value .. max_value) - * col domain is valid (date/time/timestamp/json/inet/url/uuid/...) - * col in list checks (some columns may have only certain values which are not recorded somewhere (eg as fk)) - * col conditional checks (column is not null when other column is (not) null) - -- either column_id or expression in sys.table_partitions must be populated - SELECT "column_id", "expression", 'Missing either column_id or expression' AS violation, * FROM "sys"."table_partitions" WHERE "column_id" IS NULL AND "expression" IS NULL; - SELECT "column_id", "expression", 'column_id and expression may not both be populated. One of them must be NULL' AS violation, * FROM "sys"."table_partitions" WHERE "column_id" IS NOT NULL AND "expression" IS NOT NULL; - */ - } - - private static void verifyUniqueness(String schema, String group, String[][] data, String check_type) { - final int len = data.length; - System.out.println("Checking " + len + (group != null ? " " + group : "") + " tables in schema " + schema + " for " + check_type + " violations."); - - StringBuilder sb = new StringBuilder(256); // reusable buffer to compose SQL validation queries - sb.append("SELECT COUNT(*) AS duplicates, "); - final int qry_len = sb.length(); - String tbl; - String keycols; - for (int i = 0; i < len; i++) { - if (isValidVersion(data[i][2])) { - tbl = data[i][0]; - keycols = data[i][1]; - // reuse the StringBuilder by cleaning it partial - sb.setLength(qry_len); - sb.append(keycols).append(" FROM "); - if (!tbl.startsWith("(")) { // when tbl starts with ( it is a unioned table set which we cannot prefix with a schema name qualifier - sb.append(schema).append('.'); - } - sb.append(tbl) - .append(" GROUP BY ").append(keycols) - .append(" HAVING COUNT(*) > 1;"); - validate(sb.toString(), schema, tbl, keycols, check_type); - } - } - } - - private static void verifyNotNull(String schema, String group, String[][] data, String check_type) { - final int len = data.length; - System.out.println("Checking " + len + (group != null ? " " + group : "") + " columns in schema " + schema + " for " + check_type + " violations."); - - StringBuilder sb = new StringBuilder(256); // reusable buffer to compose SQL validation queries - sb.append("SELECT "); - final int qry_len = sb.length(); - String tbl; - String col; - boolean multicolumn = false; - StringBuilder isNullCond = new StringBuilder(80); - for (int i = 0; i < len; i++) { - if (isValidVersion(data[i][2])) { - tbl = data[i][0]; - col = data[i][1]; - multicolumn = col.contains(", "); // some pkeys consist of multiple columns - isNullCond.setLength(0); // empty previous content - if (multicolumn) { - String[] cols = col.split(", "); - for (int c = 0; c < cols.length; c++) { - if (c > 0) { - isNullCond.append(" OR "); - } - isNullCond.append(cols[c]).append(" IS NULL"); - } - } else { - isNullCond.append(col).append(" IS NULL"); - } - // reuse the StringBuilder by cleaning it partial - sb.setLength(qry_len); - sb.append(col) - .append(", * FROM ").append(schema).append('.').append(tbl) - .append(" WHERE ").append(isNullCond).append(';'); - validate(sb.toString(), schema, tbl, col, check_type); - } - } - } - - private static void verifyFKs(String schema, String group, String[][] data, String check_type) { - final int len = data.length; - System.out.println("Checking " + len + (group != null ? " " + group : "") + " foreign keys in schema " + schema + " for " + check_type + " violations."); - - StringBuilder sb = new StringBuilder(400); // reusable buffer to compose SQL validation queries - sb.append("SELECT "); - final int qry_len = sb.length(); - String tbl; - String cols; - String ref_tbl; - String ref_cols; - for (int i = 0; i < len; i++) { - if (isValidVersion(data[i][4])) { - tbl = data[i][0]; - cols = data[i][1]; - ref_cols = data[i][2]; - ref_tbl = data[i][3]; - // reuse the StringBuilder by cleaning it partial - sb.setLength(qry_len); - sb.append(cols).append(", * FROM ").append(schema).append('.').append(tbl); - if (!tbl.contains(" WHERE ")) - sb.append(" WHERE "); - sb.append('(').append(cols).append(") NOT IN (SELECT ").append(ref_cols).append(" FROM "); - if (!ref_tbl.contains(".")) - sb.append(schema).append('.'); - sb.append(ref_tbl).append(");"); - validate(sb.toString(), schema, tbl, cols, check_type); - } - } - } - - private static void verifyNotNull(String schema, boolean system, String check_type) { - // fetch the NOT NULL info from the MonetDB system tables as those are leading for user tables (but not system tables) - StringBuilder sb = new StringBuilder(400); - sb.append(" from sys.columns c join sys.tables t on c.table_id = t.id join sys.schemas s on t.schema_id = s.id" - + " where t.type in (0, 10, 1, 11) and c.\"null\" = false" // t.type 0 = TABLE, 10 = SYSTEM TABLE, 1 = VIEW, 11 = SYSTEM VIEW - + " and t.system = ").append(system) - .append(" and s.name = '").append(schema).append("'"); - String qry = sb.toString(); - long count = runCountQuery(qry); - System.out.println("Checking " + count + " columns in schema " + schema + " for " + check_type + " violations."); - - Statement stmt = createStatement("verifyMaxCharStrLength()"); - ResultSet rs = null; - try { - sb.setLength(0); // empty previous usage of sb - sb.append("SELECT s.name as sch_nm, t.name as tbl_nm, c.name as col_nm") // , t.type, t.system, c.type, c.type_digits - .append(qry).append(" ORDER BY s.name, t.name, c.name;"); - qry = sb.toString(); - if (stmt != null) - rs = stmt.executeQuery(qry); - if (rs != null) { - String sch, tbl, col; - while (rs.next()) { - // retrieve meta data - sch = rs.getString(1); - tbl = rs.getString(2); - col = rs.getString(3); - // compose validation query for this specific column - sb.setLength(0); // empty previous usage of sb - sb.append("SELECT '").append(sch).append('.').append(tbl).append('.').append(col).append("' as full_col_nm, *") - .append(" FROM \"").append(sch).append("\".\"").append(tbl).append("\"") - .append(" WHERE \"").append(col).append("\" IS NULL;"); - validate(sb.toString(), sch, tbl, col, check_type); - } - } - } catch (SQLException e) { - System.out.println("Failed to execute query: " + qry); - printExceptions(e); - } - freeStmtRs(stmt, rs); - } - - private static void verifyMaxCharStrLength(String schema, boolean system, String check_type) { - // fetch the max char str len info from the MonetDB system tables as those are leading - StringBuilder sb = new StringBuilder(400); - sb.append(" from sys.columns c join sys.tables t on c.table_id = t.id join sys.schemas s on t.schema_id = s.id" - + " where t.type in (0, 10, 1, 11) and c.type_digits >= 1" // t.type 0 = TABLE, 10 = SYSTEM TABLE, 1 = VIEW, 11 = SYSTEM VIEW - + " and t.system = ").append(system) - .append(" and s.name = '").append(schema).append("'") - .append(" and c.type in ('varchar', 'char', 'clob', 'json', 'url', 'blob')"); // only for variable character/bytes data type columns - String qry = sb.toString(); - long count = runCountQuery(qry); - System.out.println("Checking " + count + " columns in schema " + schema + " for " + check_type + " violations."); - - Statement stmt = createStatement("verifyMaxCharStrLength()"); - ResultSet rs = null; - try { - sb.setLength(0); // empty previous usage of sb - sb.append("SELECT s.name as sch_nm, t.name as tbl_nm, c.name as col_nm, c.type_digits") // , t.type, t.system, c.type - .append(qry).append(" ORDER BY s.name, t.name, c.name, c.type_digits;"); - qry = sb.toString(); - if (stmt != null) - rs = stmt.executeQuery(qry); - if (rs != null) { - long max_len = 0; - String sch, tbl, col; - while (rs.next()) { - // retrieve meta data - sch = rs.getString(1); - tbl = rs.getString(2); - col = rs.getString(3); - max_len = rs.getLong(4); - // compose validation query for this specific column - sb.setLength(0); // empty previous usage of sb - sb.append("SELECT '").append(sch).append('.').append(tbl).append('.').append(col).append("' as full_col_nm, ") - .append(max_len).append(" as max_allowed_length, ") - .append("length(\"").append(col).append("\") as data_length, ") - .append("\"").append(col).append("\" as data_value") - .append(" FROM \"").append(sch).append("\".\"").append(tbl).append("\"") - .append(" WHERE \"").append(col).append("\" IS NOT NULL AND length(\"").append(col).append("\") > ").append(max_len); - validate(sb.toString(), sch, tbl, col, check_type); - } - } - } catch (SQLException e) { - System.out.println("Failed to execute query: " + qry); - printExceptions(e); - } - freeStmtRs(stmt, rs); - } - - - /* Run a validation query. - * It should result in no rows returned. - * When rows are returned those are the ones that contain violations. - * Retrieve them and convert the results into a (large) violation string - * Log/Print the violation. - */ - private static void validate(String qry, String sch, String tbl, String cols, String checktype) { - Statement stmt = createStatement("validate()"); - ResultSet rs = null; - ResultSetMetaData rsmd; - StringBuilder sb = new StringBuilder(1024); - int nr_cols; - int row; - String val; - int tp; - try { - if (verbose) { - System.out.println(qry); - } - if (stmt != null) - rs = stmt.executeQuery(qry); - if (rs != null) { - rsmd = rs.getMetaData(); - nr_cols = rsmd.getColumnCount(); - sb.setLength(0); // empty previous usage of sb - row = 0; - while (rs.next()) { - // query returns found violations - row++; - if (row == 1) { - // print result header once - for (int i = 1; i <= nr_cols; i++) { - sb.append((i > 1) ? ", " : "\t"); - sb.append(rsmd.getColumnLabel(i)); - } - sb.append('\n'); - } - // retrieve row data - for (int i = 1; i <= nr_cols; i++) { - sb.append((i > 1) ? ", " : "\t"); - val = rs.getString(i); - if (val == null || rs.wasNull()) { - sb.append("null"); - } else { - tp = rsmd.getColumnType(i); // this method is very fast, so no need to cache it outside the loop - if (tp == Types.VARCHAR || tp == Types.CHAR || tp == Types.CLOB || tp == Types.BLOB) { - sb.append('"').append(val).append('"'); - } else { - sb.append(val); - } - } - } - sb.append('\n'); - } - if (row > 0) - logViolations(checktype, sch, tbl, cols, qry, sb.toString()); - } - } catch (SQLException e) { - System.out.println("Failed to execute query: " + qry); - printExceptions(e); - } - freeStmtRs(stmt, rs); - } - - private static long runCountQuery(String from_qry) { - Statement stmt = createStatement("runCountQuery()"); - ResultSet rs = null; - long count = 0; - try { - if (stmt != null) - rs = stmt.executeQuery("SELECT COUNT(*) " + from_qry); - if (rs != null) { - if (rs.next()) { - // retrieve count data - count = rs.getLong(1); - } - } - } catch (SQLException e) { - System.out.println("Failed to execute select count(*) " + from_qry); - printExceptions(e); - } - freeStmtRs(stmt, rs); - return count; - } - - private static Statement createStatement(String method) { - try { - return con.createStatement(); - } catch (SQLException e) { - System.out.print("Failed to create Statement in " + method); - printExceptions(e); - } - return null; - } - - // private static java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss.SSS"); - private static void logViolations(String checktype, String schema, String table, String columns, String query, String violations) { -// String dts = df.format(new java.util.Date()); - StringBuilder sb = new StringBuilder(8192); -// sb.append(dts).append('\t') - sb.append(checktype).append(" violation(s) found in \"") - .append(schema).append("\".\"").append(table).append("\".\"").append(columns).append("\":\n") - .append(violations) - .append("Found using query: ").append(query).append("\n"); - System.out.println(sb.toString()); - } - - private static boolean isValidVersion(String version) { - if (version != null) { - try { - int v = Integer.parseInt(version); - return minorversion >= v; - } catch (NumberFormatException e) { - /* ignore */ - } - return false; - } - return true; // when no version string is supplied it is valid by default - } - - /* test if the standard log table already exists in target DB. - * if not try to create it. - */ -/* private static boolean create_log_table(Connection con) { - private static final String log_tbl_name = "sys.\"" + prg + "_log\""; - boolean has_log_table = false; - Statement stmt = createStatement("create_log_table()"); - ResultSet rs = null; - try { - rs = stmt.executeQuery("SELECT * FROM " + log_tbl_name + " LIMIT 1;"); - if (rs != null) { - if (rs.next()) { - has_log_table = true; - // ToDo check that the columns are the correct signature - } - } - } catch (SQLException e0) { - // we will get here when the log table does not exist yet - try { - // create it ourselves - int upd = stmt.executeUpdate("CREATE TABLE " + log_tbl_name + " IF NOT EXISTS " - + "(datetime TIMESTAMP(6) NOT NULL," - + " schema_nm VARCHAR(1024) NOT NULL," - + " table_nm VARCHAR(1024) NOT NULL," - + " column_nm VARCHAR(10240) NOT NULL," - + " validation VARCHAR(99999) NOT NULL," - + " violations VARCHAR(99999) NOT NULL);"); - if (upd >= 0) - has_log_table = true; - } catch (SQLException e) { - System.out.print("Failed to create table " + log_tbl_name); - printExceptions(e); - } - } - freeStmtRs(stmt, rs); - return has_log_table; - } -*/ - - private static void printExceptions(SQLException se) { - while (se != null) { - System.out.println(se.getSQLState() + " " + se.getMessage()); - se = se.getNextException(); - } - } - - private static void freeStmtRs(Statement stmt, ResultSet rs) { - // free resources - if (rs != null) { - try { rs.close(); } catch (SQLException e) { /* ignore */ } - } - if (stmt != null) { - try { stmt.close(); } catch (SQLException e) { /* ignore */ } - } - } - - -// ********* below are multiple 2-dimensional String arrays containing the data for constructing the validation queries ********* - // based on data from: https://dev.monetdb.org/hg/MonetDB/file/Jun2020/sql/test/sys-schema/Tests - - // static list of all sys tables with its pkey columns - // each entry contains: table_nm, pk_col_nms, from_minor_version - // data pulled from https://dev.monetdb.org/hg/MonetDB/file/Jun2020/sql/test/sys-schema/Tests/check_PrimaryKey_uniqueness.sql - private static final String[][] sys_pkeys = { - {"schemas", "id", null}, - {"table_types", "table_type_id", null}, - {"_tables", "id", null}, - {"tables", "id", null}, // is a view - {"_columns", "id", null}, - {"columns", "id", null}, // is a view - {"function_types", "function_type_id", null}, - {"function_languages", "language_id", null}, - {"functions", "id", null}, - {"systemfunctions", "function_id", null}, // has become a view in Mar2018 and maybe removed in the future as is deprecated - {"args", "id", null}, - {"types", "id", null}, - {"objects", "id, nr", null}, - {"key_types", "key_type_id", null}, - {"keys", "id", null}, - {"index_types", "index_type_id", null}, - {"idxs", "id", null}, - {"triggers", "id", null}, - {"sequences", "id", null}, - {"comments", "id", null}, - {"dependency_types", "dependency_type_id", null}, - {"dependencies", "id, depend_id", null}, - {"ids", "id", null}, // is a view - {"auths", "id", null}, - {"users", "name", null}, - {"user_role", "login_id, role_id", null}, - {"privilege_codes", "privilege_code_id", null}, - {"privileges", "obj_id, auth_id, privileges", null}, - {"querylog_catalog", "id", null}, - {"querylog_calls", "id", null}, - {"querylog_history", "id", null}, -// old {"queue", "qtag", null}, // queue has changed in Jun2020 (11.37.7), pkey was previously qtag - {"queue", "tag", "37"}, // queue has changed in Jun2020 (11.37.7), pkey is now called tag - {"optimizers", "name", null}, - {"environment", "name", null}, - {"keywords", "keyword", null}, - {"db_user_info", "name", null}, -// old {"sessions", "\"user\", login, active", null}, // sessions has changed in Jun2020 (11.37.7), pkey was previously "user", login, active - {"sessions", "sessionid", "37"}, // sessions has changed in Jun2020 (11.37.7), pkey is now called sessionid - {"statistics", "column_id", null}, - {"rejects", "rowid", "19"}, // querying this view caused problems in versions pre Jul2015, see https://www.monetdb.org/bugzilla/show_bug.cgi?id=3794 -// old {"tracelog", "event", null}, -- Error: Profiler not started. This table now (Jun2020) contains only: ticks, stmt -// {"storage", "schema, table, column", null}, // is a view on storage() - {"\"storage\"()", "schema, table, column", null}, // the function "storage"() also lists the storage for system tables - // new views introduced in Apr 2019 feature release (11.33.3) -// {"tablestorage", "schema, table", "33"}, // is a view on view storage -// {"schemastorage", "schema", "33"}, // is a view on view storage - {"storagemodelinput", "schema, table, column", null}, -// {"storagemodel", "schema, table, column", null}, // is a view on storagemodelinput -// {"tablestoragemodel", "schema, table", null}, // is a view on storagemodelinput - // new tables introduced in Apr 2019 feature release (11.33.3) - {"table_partitions", "id", "33"}, - {"range_partitions", "table_id, partition_id, minimum", "33"}, - {"value_partitions", "table_id, partition_id, \"value\"", "33"} - }; - - private static final String[][] tmp_pkeys = { - {"_tables", "id", null}, - {"_columns", "id", null}, - {"objects", "id, nr", null}, - {"keys", "id", null}, - {"idxs", "id", null}, - {"triggers", "id", null} - }; - - private static final String[][] netcdf_pkeys = { - {"netcdf_files", "file_id", null}, - {"netcdf_dims", "dim_id, file_id", null}, - {"netcdf_vars", "var_id, file_id", null}, - {"netcdf_vardim", "var_id, dim_id, file_id", null} - }; - - private static final String[][] geom_pkeys = { - {"spatial_ref_sys", "srid", null} - }; - - - // static list of all sys tables with its alternate key (unique constraint) columns - // each entry contains: table_nm, ak_col_nms, from_minor_version - // data pulled from https://dev.monetdb.org/hg/MonetDB/file/Jun2020/sql/test/sys-schema/Tests/check_AlternateKey_uniqueness.sql - private static final String[][] sys_akeys = { - {"schemas", "name", null}, - {"table_types", "table_type_name", null}, - {"_tables", "schema_id, name", null}, - {"tables", "schema_id, name", null}, // is a view - {"_columns", "table_id, name", null}, - {"columns", "table_id, name", null}, // is a view - {"_columns", "table_id, number", null}, - {"columns", "table_id, number", null}, // is a view - // The id values from sys.schemas, sys._tables, sys._columns and sys.functions combined must be exclusive (see FK from sys.privileges.obj_id) - {"(SELECT id FROM sys.schemas UNION ALL SELECT id FROM sys._tables UNION ALL SELECT id FROM sys._columns UNION ALL SELECT id FROM sys.functions) T", "T.id", null}, - {"(SELECT id FROM sys.schemas UNION ALL SELECT id FROM sys.tables UNION ALL SELECT id FROM sys.columns UNION ALL SELECT id FROM sys.functions) T", "T.id", null}, - {"function_types", "function_type_name", null}, - {"function_languages", "language_name", null}, - // the next query used to return duplicates for overloaded functions (same function but with different arg names/types), hence it has been extended - {"functions f join sys.args a on f.id=a.func_id", "schema_id, f.name, func, mod, language, f.type, side_effect, varres, vararg, a.id", null}, - {"args", "func_id, name, inout", null}, - {"types", "schema_id, systemname, sqlname", null}, - {"objects", "id, name", null}, - {"key_types", "key_type_name", null}, - {"keys", "table_id, name", null}, - {"index_types", "index_type_name", null}, - {"idxs", "table_id, name", null}, - {"triggers", "table_id, name", null}, - {"sequences", "schema_id, name", null}, - {"comments", "id", null}, - {"dependency_types", "dependency_type_name", null}, - {"auths", "name", null}, // is this always unique?? isn't it possible to define a user and a role with the same name? - {"privilege_codes", "privilege_code_name", null}, - {"optimizers", "def", null}, - // new tables introduced in Apr 2019 feature release (11.33.3) - {"table_partitions WHERE column_id IS NOT NULL", "table_id, column_id", "33"}, // requires WHERE "column_id" IS NOT NULL - {"table_partitions WHERE \"expression\" IS NOT NULL", "table_id, \"expression\"", "33"}, // requires WHERE "expression" IS NOT NULL - {"range_partitions", "table_id, partition_id, \"maximum\"", "33"} - }; - - private static final String[][] tmp_akeys = { - {"_tables", "schema_id, name", null}, - {"_columns", "table_id, name", null}, - {"_columns", "table_id, number", null}, - {"objects", "id, name", null}, - {"keys", "table_id, name", null}, - {"idxs", "table_id, name", null}, - {"triggers", "table_id, name", null} - }; - - private static final String[][] netcdf_akeys = { - {"netcdf_files", "location", null} - }; - - private static final String[][] geom_akeys = { - {"spatial_ref_sys", "auth_name, auth_srid, srtext, proj4text", null} - }; - - - // static list of all sys tables with its foreign key columns - // each entry contains: table_nm, fk_col_nms, ref_col_nms, ref_tbl_nm, from_minor_version - // data pulled from https://dev.monetdb.org/hg/MonetDB/file/Jun2020/sql/test/sys-schema/Tests/check_ForeignKey_referential_integrity.sql - private static final String[][] sys_fkeys = { - {"schemas", "authorization", "id", "auths", null}, - {"schemas", "owner", "id", "auths", null}, - {"_tables", "schema_id", "id", "schemas", null}, - {"tables", "schema_id", "id", "schemas", null}, - {"_tables", "type", "table_type_id", "table_types", null}, - {"tables", "type", "table_type_id", "table_types", null}, - {"_columns", "table_id", "id", "_tables", null}, - {"columns", "table_id", "id", "tables", null}, - {"_columns", "type", "sqlname", "types", null}, - {"columns", "type", "sqlname", "types", null}, - {"functions", "schema_id", "id", "schemas", null}, - {"functions", "type", "function_type_id", "function_types", null}, - {"functions", "language", "language_id", "function_languages", null}, - // system functions should refer only to functions in MonetDB system schemas (on Dec2016 these are: sys, json, profiler and bam) - {"functions WHERE system AND ", "schema_id", "id", "schemas WHERE system", null}, - {"args", "func_id", "id", "functions", null}, - {"args", "type", "sqlname", "types", null}, - {"types", "schema_id", "id", "schemas", null}, - // {"types WHERE schema_id <> 0 AND ", "schema_id", "id", "schemas", null}, - {"objects", "id", "id", "ids", null}, - {"ids WHERE obj_type IN ('key', 'index') AND ", "id", "id", "objects", null}, - {"keys", "id", "id", "objects", null}, - {"keys", "table_id", "id", "_tables", null}, - {"keys", "table_id", "id", "tables", null}, - {"keys", "type", "key_type_id", "key_types", null}, - {"keys WHERE rkey <> -1 AND ", "rkey", "id", "keys", null}, -// SELECT * FROM sys.keys WHERE action <> -1 AND action NOT IN (SELECT id FROM sys.?); -- TODO: find out which action values are valid and what they mean. - {"idxs", "id", "id", "objects", null}, - {"idxs", "table_id", "id", "_tables", null}, - {"idxs", "table_id", "id", "tables", null}, - {"idxs", "type", "index_type_id", "index_types", null}, - {"sequences", "schema_id", "id", "schemas", null}, - {"triggers", "table_id", "id", "_tables", null}, - {"triggers", "table_id", "id", "tables", null}, - {"comments", "id", "id", "ids", null}, - {"dependencies", "id", "id", "ids", null}, - {"dependencies", "depend_id", "id", "ids", null}, - {"dependencies", "depend_type", "dependency_type_id", "dependency_types", null}, - {"dependencies", "id, depend_id, depend_type", "v.id, v.used_by_id, v.depend_type", "dependencies_vw v", null}, - {"auths WHERE grantor > 0 AND ", "grantor", "id", "auths", null}, - {"users", "name", "name", "auths", null}, - {"users", "default_schema", "id", "schemas", null}, - {"db_user_info", "name", "name", "auths", null}, - {"db_user_info", "default_schema", "id", "schemas", null}, - {"user_role", "login_id", "id", "auths", null}, - {"user_role", "login_id", "a.id", "auths a WHERE a.name IN (SELECT u.name FROM sys.users u)", null}, - {"user_role", "role_id", "id", "auths", null}, - {"user_role", "role_id", "a.id", "auths a WHERE a.name IN (SELECT u.name FROM sys.users u)", null}, - {"user_role", "role_id", "id", "roles", null} -/* hier verder afmaken -SELECT * FROM sys.privileges WHERE obj_id NOT IN (SELECT id FROM sys.schemas UNION ALL SELECT id FROM sys._tables UNION ALL SELECT id FROM sys._columns UNION ALL SELECT id FROM sys.functions); -SELECT * FROM sys.privileges WHERE auth_id NOT IN (SELECT id FROM sys.auths); -SELECT * FROM sys.privileges WHERE grantor NOT IN (SELECT id FROM sys.auths) AND grantor > 0; -SELECT * FROM sys.privileges WHERE privileges NOT IN (SELECT privilege_code_id FROM sys.privilege_codes); ---SELECT * FROM sys.privileges WHERE privileges NOT IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,32); -- old check before table sys.privilege_codes existed - -SELECT * FROM sys.querylog_catalog WHERE owner NOT IN (SELECT name FROM sys.users); -SELECT * FROM sys.querylog_catalog WHERE pipe NOT IN (SELECT name FROM sys.optimizers); -SELECT * FROM sys.querylog_calls WHERE id NOT IN (SELECT id FROM sys.querylog_catalog); -SELECT * FROM sys.querylog_history WHERE id NOT IN (SELECT id FROM sys.querylog_catalog); -SELECT * FROM sys.querylog_history WHERE owner NOT IN (SELECT name FROM sys.users); -SELECT * FROM sys.querylog_history WHERE pipe NOT IN (SELECT name FROM sys.optimizers); - -SELECT * FROM sys.queue WHERE tag > cast(0 as oid) AND tag NOT IN (SELECT tag FROM sys.queue); -SELECT * FROM sys.queue WHERE tag > cast(0 as oid) AND tag NOT IN (SELECT cast(tag as oid) FROM sys.queue); -SELECT * FROM sys.queue WHERE tag NOT IN (SELECT cast(tag as oid) FROM sys.queue); -SELECT * FROM sys.queue WHERE "username" NOT IN (SELECT name FROM sys.users); - -SELECT * FROM sys.sessions WHERE "username" NOT IN (SELECT name FROM sys.users); - -SELECT * FROM sys.statistics WHERE column_id NOT IN (SELECT id FROM sys._columns UNION ALL SELECT id FROM tmp._columns); -SELECT * FROM sys.statistics WHERE type NOT IN (SELECT sqlname FROM sys.types); - -SELECT * FROM sys.storage() WHERE schema NOT IN (SELECT name FROM sys.schemas); -SELECT * FROM sys.storage() WHERE table NOT IN (SELECT name FROM sys._tables UNION ALL SELECT name FROM tmp._tables); -SELECT * FROM sys.storage() WHERE (schema, table) NOT IN (SELECT sch.name, tbl.name FROM sys.schemas AS sch JOIN sys.tables AS tbl ON sch.id = tbl.schema_id); -SELECT * FROM sys.storage() WHERE column NOT IN (SELECT name FROM sys._columns UNION ALL SELECT name FROM tmp._columns UNION ALL SELECT name FROM sys.keys UNION ALL SELECT name FROM tmp.keys UNION ALL SELECT name FROM sys.idxs UNION ALL SELECT name FROM tmp.idxs); -SELECT * FROM sys.storage() WHERE type NOT IN (SELECT sqlname FROM sys.types); - -SELECT * FROM sys.storage WHERE schema NOT IN (SELECT name FROM sys.schemas); -SELECT * FROM sys.storage WHERE table NOT IN (SELECT name FROM sys._tables UNION ALL SELECT name FROM tmp._tables); -SELECT * FROM sys.storage WHERE (schema, table) NOT IN (SELECT sch.name, tbl.name FROM sys.schemas AS sch JOIN sys.tables AS tbl ON sch.id = tbl.schema_id); -SELECT * FROM sys.storage WHERE column NOT IN (SELECT name FROM sys._columns UNION ALL SELECT name FROM tmp._columns UNION ALL SELECT name FROM sys.keys UNION ALL SELECT name FROM tmp.keys UNION ALL SELECT name FROM sys.idxs UNION ALL SELECT name FROM tmp.idxs); -SELECT * FROM sys.storage WHERE type NOT IN (SELECT sqlname FROM sys.types); - -SELECT * FROM sys.tablestorage WHERE schema NOT IN (SELECT name FROM sys.schemas); -SELECT * FROM sys.tablestorage WHERE table NOT IN (SELECT name FROM sys._tables UNION ALL SELECT name FROM tmp._tables); -SELECT * FROM sys.tablestorage WHERE (schema, table) NOT IN (SELECT sch.name, tbl.name FROM sys.schemas AS sch JOIN sys.tables AS tbl ON sch.id = tbl.schema_id); - -SELECT * FROM sys.schemastorage WHERE schema NOT IN (SELECT name FROM sys.schemas); - -SELECT * FROM sys.storagemodel WHERE schema NOT IN (SELECT name FROM sys.schemas); -SELECT * FROM sys.storagemodel WHERE table NOT IN (SELECT name FROM sys._tables UNION ALL SELECT name FROM tmp._tables); -SELECT * FROM sys.storagemodel WHERE (schema, table) NOT IN (SELECT sch.name, tbl.name FROM sys.schemas AS sch JOIN sys.tables AS tbl ON sch.id = tbl.schema_id); -SELECT * FROM sys.storagemodel WHERE column NOT IN (SELECT name FROM sys._columns UNION ALL SELECT name FROM tmp._columns UNION ALL SELECT name FROM sys.keys UNION ALL SELECT name FROM tmp.keys UNION ALL SELECT name FROM sys.idxs UNION ALL SELECT name FROM tmp.idxs); -SELECT * FROM sys.storagemodel WHERE type NOT IN (SELECT sqlname FROM sys.types); - -SELECT * FROM sys.storagemodelinput WHERE schema NOT IN (SELECT name FROM sys.schemas); -SELECT * FROM sys.storagemodelinput WHERE table NOT IN (SELECT name FROM sys._tables UNION ALL SELECT name FROM tmp._tables); -SELECT * FROM sys.storagemodelinput WHERE (schema, table) NOT IN (SELECT sch.name, tbl.name FROM sys.schemas AS sch JOIN sys.tables AS tbl ON sch.id = tbl.schema_id); -SELECT * FROM sys.storagemodelinput WHERE column NOT IN (SELECT name FROM sys._columns UNION ALL SELECT name FROM tmp._columns UNION ALL SELECT name FROM sys.keys UNION ALL SELECT name FROM tmp.keys UNION ALL SELECT name FROM sys.idxs UNION ALL SELECT name FROM tmp.idxs); -SELECT * FROM sys.storagemodelinput WHERE type NOT IN (SELECT sqlname FROM sys.types); - -SELECT schema, table, rowcount, columnsize, heapsize, hashsize, imprintsize, orderidxsize FROM sys.tablestoragemodel WHERE schema NOT IN (SELECT name FROM sys.schemas); -SELECT schema, table, rowcount, columnsize, heapsize, hashsize, imprintsize, orderidxsize FROM sys.tablestoragemodel WHERE table NOT IN (SELECT name FROM sys._tables UNION ALL SELECT name FROM tmp._tables); -SELECT schema, table, rowcount, columnsize, heapsize, hashsize, imprintsize, orderidxsize FROM sys.tablestoragemodel WHERE (schema, table) NOT IN (SELECT sch.name, tbl.name FROM sys.schemas AS sch JOIN sys.tables AS tbl ON sch.id = tbl.schema_id); - --- new tables introduced in 2019 -SELECT * FROM sys.table_partitions WHERE "table_id" NOT IN (SELECT id FROM sys._tables); -SELECT * FROM sys.table_partitions WHERE "column_id" IS NOT NULL AND "column_id" NOT IN (SELECT id FROM sys._columns); -SELECT * FROM sys.table_partitions WHERE "type" NOT IN (5,6,9,10); -- 5=By Column Range (1+4), 6=By Expression Range (2+4), 9=By Column Value (1+8), 10=By Expression Value (2+8), see sql_catalog.h #define PARTITION_* - -SELECT * FROM sys.range_partitions WHERE "table_id" NOT IN (SELECT id FROM sys._tables); -SELECT * FROM sys.range_partitions WHERE "partition_id" NOT IN (SELECT id FROM sys.table_partitions); - -SELECT * FROM sys.value_partitions WHERE "table_id" NOT IN (SELECT id FROM sys._tables); -SELECT * FROM sys.value_partitions WHERE "partition_id" NOT IN (SELECT id FROM sys.table_partitions); -*/ - }; - - private static final String[][] tmp_fkeys = { - {"_tables", "schema_id", "id", "sys.schemas", null}, - {"_tables", "type", "table_type_id", "sys.table_types", null}, - {"_columns", "table_id", "id", "_tables", null}, - {"_columns", "type", "sqlname", "sys.types", null}, - {"keys", "table_id", "id", "_tables", null}, - {"keys", "type", "key_type_id", "sys.key_types", null}, - {"keys WHERE rkey <> -1 AND ", "rkey", "id", "keys", null}, -// SELECT * FROM tmp.keys WHERE action <> -1 AND action NOT IN (SELECT id FROM tmp.?); -- TODO: find out which action values are valid and what they mean. - {"idxs", "id", "id", "objects", null}, - {"idxs", "table_id", "id", "_tables", null}, - {"idxs", "type", "index_type_id", "sys.index_types", null}, - {"triggers", "table_id", "id", "_tables", null} - // nog verder afmaken, zie fkey data hierboven - }; - - private static final String[][] netcdf_fkeys = { - {"netcdf_attrs", "file_id", "file_id", "netcdf_files", null}, - {"netcdf_dims", "file_id", "file_id", "netcdf_files", null}, - {"netcdf_vars", "file_id", "file_id", "netcdf_files", null}, - {"netcdf_vardim", "file_id", "file_id", "netcdf_files", null}, - {"netcdf_vardim", "dim_id", "dim_id", "netcdf_dims", null}, - {"netcdf_vardim", "dim_id, file_id", "dim_id, file_id", "netcdf_dims", null}, - {"netcdf_vardim", "var_id", "var_id", "netcdf_vars", null}, - {"netcdf_vardim", "var_id, file_id", "var_id, file_id", "netcdf_vars", null} - }; - - private static final String[][] geom_fkeys = { - {"spatial_ref_sys", "auth_srid", "srid", "spatial_ref_sys", null} - }; - - - // static list of all sys tables with its not null constraint columns - // each entry contains: table_nm, col_nm, from_minor_version - // data pulled from https://dev.monetdb.org/hg/MonetDB/file/Jun2020/sql/test/sys-schema/Tests/check_Not_Nullable_columns.sql - private static final String[][] sys_notnull = { - {"_columns", "id", null}, - {"_columns", "name", null}, - {"_columns", "type", null}, - {"_columns", "type_digits", null}, - {"_columns", "type_scale", null}, - {"_columns", "table_id", null}, - {"_columns", "\"null\"", null}, - {"_columns", "number", null}, - {"_tables", "id", null}, - {"_tables", "name", null}, - {"_tables", "schema_id", null}, - {"_tables", "type", null}, - {"_tables", "system", null}, - {"_tables", "commit_action", null}, - {"_tables", "access", null}, - {"args", "id", null}, - {"args", "func_id", null}, - {"args", "name", null}, - {"args", "type", null}, - {"args", "type_digits", null}, - {"args", "type_scale", null}, - {"args", "inout", null}, - {"args", "number", null}, - {"auths", "id", null}, - {"auths", "name", null}, - {"auths", "grantor", null}, - {"db_user_info", "name", null}, - {"db_user_info", "fullname", null}, - {"db_user_info", "default_schema", null}, - {"dependencies", "id", null}, - {"dependencies", "depend_id", null}, - {"dependencies", "depend_type", null}, - {"function_languages", "language_id", null}, - {"function_languages", "language_name", null}, - {"function_types", "function_type_id", null}, - {"function_types", "function_type_name", null}, - {"function_types", "function_type_keyword", null}, - {"functions", "id", null}, - {"functions", "name", null}, - {"functions", "func", null}, - {"functions", "mod", null}, - {"functions", "language", null}, - {"functions", "type", null}, - {"functions", "side_effect", null}, - {"functions", "varres", null}, - {"functions", "vararg", null}, - {"functions", "schema_id", null}, - {"functions", "system", null}, - {"idxs", "id", null}, - {"idxs", "table_id", null}, - {"idxs", "type", null}, - {"idxs", "name", null}, - {"index_types", "index_type_id", null}, - {"index_types", "index_type_name", null}, - {"key_types", "key_type_id", null}, - {"key_types", "key_type_name", null}, - {"keys", "id", null}, - {"keys", "table_id", null}, - {"keys", "type", null}, - {"keys", "name", null}, - {"keys", "rkey", null}, - {"keys", "action", null}, - {"keywords", "keyword", null}, - {"objects", "id", null}, - {"objects", "name", null}, - {"objects", "nr", null}, - {"optimizers", "name", null}, - {"optimizers", "def", null}, - {"optimizers", "status", null}, - {"privilege_codes", "privilege_code_id", null}, - {"privilege_codes", "privilege_code_name", null}, - {"privileges", "obj_id", null}, - {"privileges", "auth_id", null}, - {"privileges", "privileges", null}, - {"privileges", "grantor", null}, - {"privileges", "grantable", null}, - {"schemas", "id", null}, - {"schemas", "name", null}, - {"schemas", "authorization", null}, - {"schemas", "owner", null}, - {"schemas", "system", null}, - {"sequences", "id", null}, - {"sequences", "schema_id", null}, - {"sequences", "name", null}, - {"sequences", "start", null}, - {"sequences", "minvalue", null}, - {"sequences", "maxvalue", null}, - {"sequences", "increment", null}, - {"sequences", "cacheinc", null}, - {"sequences", "cycle", null}, - {"statistics", "column_id", null}, - {"statistics", "type", null}, - {"statistics", "width", null}, - {"statistics", "stamp", null}, - {"statistics", "\"sample\"", null}, - {"statistics", "count", null}, - {"statistics", "\"unique\"", null}, - {"statistics", "nils", null}, - {"statistics", "sorted", null}, - {"statistics", "revsorted", null}, -/* temporary disabled, TODO re-enable - {"storage", "schema", null}, - {"storage", "table", null}, - {"storage", "column", null}, - {"storage", "type", null}, - {"storage", "mode", null}, - {"storage", "location", null}, - {"storage", "count", null}, - {"storage", "typewidth", null}, - {"storage", "columnsize", null}, - {"storage", "heapsize", null}, - {"storage", "hashes", null}, - {"storage", "phash", null}, - {"storage", "imprints", null}, - {"storage", "orderidx", null}, -*/ {"storagemodelinput", "schema", null}, - {"storagemodelinput", "table", null}, - {"storagemodelinput", "column", null}, - {"storagemodelinput", "type", null}, - {"storagemodelinput", "typewidth", null}, - {"storagemodelinput", "count", null}, - {"storagemodelinput", "\"distinct\"", null}, - {"storagemodelinput", "atomwidth", null}, - {"storagemodelinput", "reference", null}, - {"storagemodelinput", "sorted", null}, - {"storagemodelinput", "\"unique\"", null}, - {"storagemodelinput", "isacolumn", null}, - {"table_types", "table_type_id", null}, - {"table_types", "table_type_name", null}, - {"tables", "id", null}, - {"tables", "name", null}, - {"tables", "schema_id", null}, - {"tables", "type", null}, - {"tables", "system", null}, - {"tables", "commit_action", null}, - {"tables", "access", null}, - {"tables", "temporary", null}, - {"tracelog", "ticks", null}, - {"tracelog", "stmt", null}, - {"triggers", "id", null}, - {"triggers", "name", null}, - {"triggers", "table_id", null}, - {"triggers", "time", null}, - {"triggers", "orientation", null}, - {"triggers", "event", null}, - {"triggers", "statement", null}, - {"types", "id", null}, - {"types", "systemname", null}, - {"types", "sqlname", null}, - {"types", "digits", null}, - {"types", "scale", null}, - {"types", "radix", null}, - {"types", "eclass", null}, - {"types", "schema_id", null}, - {"user_role", "login_id", null}, - {"user_role", "role_id", null}, - {"users", "name", null}, - {"users", "fullname", null}, - {"users", "default_schema", null}, - {"var_values", "var_name", null}, - {"var_values", "value", null}, - // new tables introduced in Apr 2019 feature release (11.33.3) - {"range_partitions", "table_id", "33"}, - {"range_partitions", "partition_id", "33"}, - {"range_partitions", "with_nulls", "33"}, - {"table_partitions", "id", "33"}, - {"table_partitions", "table_id", "33"}, - {"table_partitions", "type", "33"}, - {"value_partitions", "table_id", "33"}, - {"value_partitions", "partition_id", "33"}, - {"value_partitions", "value", "33"} // ?? Can this be null when WITH NULL VALUES is specified. - }; - - private static final String[][] tmp_notnull = { - {"_columns", "id", null}, - {"_columns", "name", null}, - {"_columns", "type", null}, - {"_columns", "type_digits", null}, - {"_columns", "type_scale", null}, - {"_columns", "table_id", null}, - {"_columns", "\"null\"", null}, - {"_columns", "number", null}, - {"_tables", "id", null}, - {"_tables", "name", null}, - {"_tables", "schema_id", null}, - {"_tables", "type", null}, - {"_tables", "system", null}, - {"_tables", "commit_action", null}, - {"_tables", "access", null}, - {"idxs", "id", null}, - {"idxs", "table_id", null}, - {"idxs", "type", null}, - {"idxs", "name", null}, - {"keys", "id", null}, - {"keys", "table_id", null}, - {"keys", "type", null}, - {"keys", "name", null}, - {"keys", "rkey", null}, - {"keys", "action", null}, - {"objects", "id", null}, - {"objects", "name", null}, - {"objects", "nr", null}, - {"triggers", "id", null}, - {"triggers", "name", null}, - {"triggers", "table_id", null}, - {"triggers", "time", null}, - {"triggers", "orientation", null}, - {"triggers", "event", null}, - {"triggers", "statement", null} - }; - - private static final String[][] netcdf_notnull = { - {"netcdf_files", "file_id", null}, - {"netcdf_files", "location", null}, - {"netcdf_dims", "dim_id", null}, - {"netcdf_dims", "file_id", null}, - {"netcdf_dims", "name", null}, - {"netcdf_dims", "length", null}, - {"netcdf_vars", "var_id", null}, - {"netcdf_vars", "file_id", null}, - {"netcdf_vars", "name", null}, - {"netcdf_vars", "vartype", null}, - {"netcdf_vardim", "var_id", null}, - {"netcdf_vardim", "dim_id", null}, - {"netcdf_vardim", "file_id", null}, - {"netcdf_vardim", "dimpos", null}, - {"netcdf_attrs", "obj_name", null}, - {"netcdf_attrs", "att_name", null}, - {"netcdf_attrs", "att_type", null}, - {"netcdf_attrs", "value", null}, - {"netcdf_attrs", "file_id", null}, - {"netcdf_attrs", "gr_name", null} - }; - - private static final String[][] geom_notnull = { - {"spatial_ref_sys", "srid", null}, - {"spatial_ref_sys", "auth_name", null}, - {"spatial_ref_sys", "auth_srid", null}, - {"spatial_ref_sys", "srtext", null}, - {"spatial_ref_sys", "proj4text", null} - }; -}