Mercurial > hg > monetdb-java
comparison src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java @ 302:1b6c514106ce
Added table aliases and use them in all meta data SQL queries to reduce query size.
Also use JOIN syntax in FROM clause instead of old way of joining in WHERE clause. This further reduces size.
In getIndexInfo() no longer issue a SELECT COUNT(*) query when the schema or table name contains wildcard: %.
In getIndexInfo() added missing join condition
AND i.\"table_id\" = k.\"table_id\"
to make sure the index and the key constraint both reference the same table
and extended the output to also lists info for primary keys (which also use an internal hash index).
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 15 Aug 2019 19:01:49 +0200 (2019-08-15) |
parents | 8cc3b51d1984 |
children | a91168efdf27 |
comparison
equal
deleted
inserted
replaced
301:59bc8bebbfe9 | 302:1b6c514106ce |
---|---|
19 | 19 |
20 /** | 20 /** |
21 * A DatabaseMetaData object suitable for the MonetDB database. | 21 * A DatabaseMetaData object suitable for the MonetDB database. |
22 * | 22 * |
23 * @author Fabian Groffen, Martin van Dinther | 23 * @author Fabian Groffen, Martin van Dinther |
24 * @version 0.7 | 24 * @version 0.8 |
25 */ | 25 */ |
26 public class MonetDatabaseMetaData | 26 public class MonetDatabaseMetaData |
27 extends MonetWrapper | 27 extends MonetWrapper |
28 implements DatabaseMetaData | 28 implements DatabaseMetaData |
29 { | 29 { |
955 * The SQL Integrity Enhancement facility offers additional tools for referential integrity, | 955 * The SQL Integrity Enhancement facility offers additional tools for referential integrity, |
956 * CHECK constraint clauses, and DEFAULT clauses. Referential integrity allows specification of | 956 * CHECK constraint clauses, and DEFAULT clauses. Referential integrity allows specification of |
957 * primary and foreign keys with the requirement that no foreign key row may be inserted or | 957 * primary and foreign keys with the requirement that no foreign key row may be inserted or |
958 * updated unless a matching primary key row exists. Check clauses allow specification of | 958 * updated unless a matching primary key row exists. Check clauses allow specification of |
959 * inter-column constraints to be maintained by the database system. | 959 * inter-column constraints to be maintained by the database system. |
960 * Default clauses provide optional default values for missing data. | 960 * Default clauses provide optional default values for missing data. |
961 * | 961 * |
962 * We currently do not supprt CHECK constraints (see bug 3568) nor deferrable FK constraints. | 962 * We currently do not supprt CHECK constraints (see bug 3568) nor deferrable FK constraints. |
963 * | 963 * |
964 * @return true if so | 964 * @return true if so |
965 */ | 965 */ |
1712 ) throws SQLException | 1712 ) throws SQLException |
1713 { | 1713 { |
1714 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); | 1714 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); |
1715 final StringBuilder query = new StringBuilder(980); | 1715 final StringBuilder query = new StringBuilder(980); |
1716 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + | 1716 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + |
1717 "\"schemas\".\"name\" AS \"PROCEDURE_SCHEM\", " + | 1717 "s.\"name\" AS \"PROCEDURE_SCHEM\", " + |
1718 "\"functions\".\"name\" AS \"PROCEDURE_NAME\", " + | 1718 "f.\"name\" AS \"PROCEDURE_NAME\", " + |
1719 "cast(null as char(1)) AS \"Field4\", " + | 1719 "cast(null as char(1)) AS \"Field4\", " + |
1720 "cast(null as char(1)) AS \"Field5\", " + | 1720 "cast(null as char(1)) AS \"Field5\", " + |
1721 "cast(null as char(1)) AS \"Field6\", ") | 1721 "cast(null as char(1)) AS \"Field6\", ") |
1722 .append(useCommentsTable ? "COALESCE(\"comments\".\"remark\", cast(\"functions\".\"func\" as varchar(9999)))" : "cast(\"functions\".\"func\" as varchar(9999))").append(" AS \"REMARKS\", " + | 1722 .append(useCommentsTable ? "COALESCE(cm.\"remark\", cast(f.\"func\" as varchar(9999)))" : "cast(f.\"func\" as varchar(9999))").append(" AS \"REMARKS\", " + |
1723 // in MonetDB procedures have no return value by design. | 1723 // in MonetDB procedures have no return value by design. |
1724 "cast(").append(DatabaseMetaData.procedureNoResult).append(" AS smallint) AS \"PROCEDURE_TYPE\", " + | 1724 "cast(").append(DatabaseMetaData.procedureNoResult).append(" AS smallint) AS \"PROCEDURE_TYPE\", " + |
1725 // only the id value uniquely identifies a procedure. Include it to be able to differentiate between multiple overloaded procedures with the same name | 1725 // only the id value uniquely identifies a procedure. Include it to be able to differentiate between multiple overloaded procedures with the same name |
1726 "cast(\"functions\".\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + | 1726 "cast(f.\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + |
1727 "FROM \"sys\".\"functions\" JOIN \"sys\".\"schemas\" ON (\"functions\".\"schema_id\" = \"schemas\".\"id\") "); | 1727 "FROM \"sys\".\"functions\" f JOIN \"sys\".\"schemas\" s ON (f.\"schema_id\" = s.\"id\") "); |
1728 if (useCommentsTable) { | 1728 if (useCommentsTable) { |
1729 query.append("LEFT OUTER JOIN \"sys\".\"comments\" ON (\"functions\".\"id\" = \"comments\".\"id\") "); | 1729 query.append("LEFT OUTER JOIN \"sys\".\"comments\" cm ON (f.\"id\" = cm.\"id\") "); |
1730 } | 1730 } |
1731 // include procedures only (type = 2). Others will be returned via getFunctions() | 1731 // include procedures only (type = 2). Others will be returned via getFunctions() |
1732 query.append("WHERE \"functions\".\"type\" = 2"); | 1732 query.append("WHERE f.\"type\" = 2"); |
1733 | 1733 |
1734 if (catalog != null && !catalog.isEmpty()) { | 1734 if (catalog != null && !catalog.isEmpty()) { |
1735 // non-empty catalog selection. | 1735 // non-empty catalog selection. |
1736 // as we do not support catalogs this always results in no rows returned | 1736 // as we do not support catalogs this always results in no rows returned |
1737 query.append(" AND 1 = 0"); | 1737 query.append(" AND 1 = 0"); |
1738 } else { | 1738 } else { |
1739 if (schemaPattern != null) { | 1739 if (schemaPattern != null) { |
1740 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 1740 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
1741 } | 1741 } |
1742 if (procedureNamePattern != null) { | 1742 if (procedureNamePattern != null) { |
1743 query.append(" AND \"functions\".\"name\" ").append(composeMatchPart(procedureNamePattern)); | 1743 query.append(" AND f.\"name\" ").append(composeMatchPart(procedureNamePattern)); |
1744 } | 1744 } |
1745 } | 1745 } |
1746 | 1746 |
1747 query.append(" ORDER BY \"PROCEDURE_SCHEM\", \"PROCEDURE_NAME\", \"SPECIFIC_NAME\""); | 1747 query.append(" ORDER BY \"PROCEDURE_SCHEM\", \"PROCEDURE_NAME\", \"SPECIFIC_NAME\""); |
1748 | 1748 |
1824 final String procedureNamePattern, | 1824 final String procedureNamePattern, |
1825 final String columnNamePattern | 1825 final String columnNamePattern |
1826 ) throws SQLException { | 1826 ) throws SQLException { |
1827 final StringBuilder query = new StringBuilder(2900); | 1827 final StringBuilder query = new StringBuilder(2900); |
1828 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + | 1828 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + |
1829 "\"schemas\".\"name\" AS \"PROCEDURE_SCHEM\", " + | 1829 "s.\"name\" AS \"PROCEDURE_SCHEM\", " + |
1830 "\"functions\".\"name\" AS \"PROCEDURE_NAME\", " + | 1830 "f.\"name\" AS \"PROCEDURE_NAME\", " + |
1831 "\"args\".\"name\" AS \"COLUMN_NAME\", " + | 1831 "a.\"name\" AS \"COLUMN_NAME\", " + |
1832 "cast(CASE \"args\".\"inout\"" + | 1832 "cast(CASE a.\"inout\"" + |
1833 " WHEN 0 THEN (CASE \"args\".\"number\" WHEN 0 THEN ").append(DatabaseMetaData.procedureColumnReturn).append(" ELSE ").append(DatabaseMetaData.procedureColumnOut).append(" END)" + | 1833 " WHEN 0 THEN (CASE a.\"number\" WHEN 0 THEN ").append(DatabaseMetaData.procedureColumnReturn).append(" ELSE ").append(DatabaseMetaData.procedureColumnOut).append(" END)" + |
1834 " WHEN 1 THEN ").append(DatabaseMetaData.procedureColumnIn) | 1834 " WHEN 1 THEN ").append(DatabaseMetaData.procedureColumnIn) |
1835 .append(" ELSE ").append(DatabaseMetaData.procedureColumnUnknown).append(" END AS smallint) AS \"COLUMN_TYPE\", " + | 1835 .append(" ELSE ").append(DatabaseMetaData.procedureColumnUnknown).append(" END AS smallint) AS \"COLUMN_TYPE\", " + |
1836 "cast(").append(MonetDriver.getSQLTypeMap("\"args\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + | 1836 "cast(").append(MonetDriver.getSQLTypeMap("a.\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + |
1837 "\"args\".\"type\" AS \"TYPE_NAME\", " + | 1837 "a.\"type\" AS \"TYPE_NAME\", " + |
1838 "CASE \"args\".\"type\" WHEN 'tinyint' THEN 3 WHEN 'smallint' THEN 5 WHEN 'int' THEN 10 WHEN 'bigint' THEN 19 WHEN 'hugeint' THEN 38 WHEN 'oid' THEN 19 WHEN 'wrd' THEN 19 ELSE \"args\".\"type_digits\" END AS \"PRECISION\", " + | 1838 "CASE a.\"type\" WHEN 'tinyint' THEN 3 WHEN 'smallint' THEN 5 WHEN 'int' THEN 10 WHEN 'bigint' THEN 19 WHEN 'hugeint' THEN 38 WHEN 'oid' THEN 19 WHEN 'wrd' THEN 19 ELSE a.\"type_digits\" END AS \"PRECISION\", " + |
1839 "CASE \"args\".\"type\" WHEN 'tinyint' THEN 1 WHEN 'smallint' THEN 2 WHEN 'int' THEN 4 WHEN 'bigint' THEN 8 WHEN 'hugeint' THEN 16 WHEN 'oid' THEN 8 WHEN 'wrd' THEN 8 ELSE \"args\".\"type_digits\" END AS \"LENGTH\", " + | 1839 "CASE a.\"type\" WHEN 'tinyint' THEN 1 WHEN 'smallint' THEN 2 WHEN 'int' THEN 4 WHEN 'bigint' THEN 8 WHEN 'hugeint' THEN 16 WHEN 'oid' THEN 8 WHEN 'wrd' THEN 8 ELSE a.\"type_digits\" END AS \"LENGTH\", " + |
1840 "cast(CASE WHEN \"args\".\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric','time','timetz','timestamp','timestamptz','sec_interval') THEN \"args\".\"type_scale\" ELSE NULL END AS smallint) AS \"SCALE\", " + | 1840 "cast(CASE WHEN a.\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric','time','timetz','timestamp','timestamptz','sec_interval') THEN a.\"type_scale\" ELSE NULL END AS smallint) AS \"SCALE\", " + |
1841 "cast(CASE WHEN \"args\".\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric') THEN 10 WHEN \"args\".\"type\" IN ('real','float','double') THEN 2 ELSE NULL END AS smallint) AS \"RADIX\", " + | 1841 "cast(CASE WHEN a.\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric') THEN 10 WHEN a.\"type\" IN ('real','float','double') THEN 2 ELSE NULL END AS smallint) AS \"RADIX\", " + |
1842 "cast(").append(DatabaseMetaData.procedureNullableUnknown).append(" AS smallint) AS \"NULLABLE\", " + | 1842 "cast(").append(DatabaseMetaData.procedureNullableUnknown).append(" AS smallint) AS \"NULLABLE\", " + |
1843 "cast(null as char(1)) AS \"REMARKS\", " + | 1843 "cast(null as char(1)) AS \"REMARKS\", " + |
1844 "cast(null as char(1)) AS \"COLUMN_DEF\", " + | 1844 "cast(null as char(1)) AS \"COLUMN_DEF\", " + |
1845 "cast(0 as int) AS \"SQL_DATA_TYPE\", " + | 1845 "cast(0 as int) AS \"SQL_DATA_TYPE\", " + |
1846 "cast(0 as int) AS \"SQL_DATETIME_SUB\", " + | 1846 "cast(0 as int) AS \"SQL_DATETIME_SUB\", " + |
1847 "cast(CASE WHEN \"args\".\"type\" IN ('char','varchar','clob') THEN \"args\".\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " + | 1847 "cast(CASE WHEN a.\"type\" IN ('char','varchar','clob') THEN a.\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " + |
1848 // in MonetDB procedures have no return value by design. The arguments in sys.args are numbered from 0 so we must add 1 to comply with the API specification. | 1848 // in MonetDB procedures have no return value by design. The arguments in sys.args are numbered from 0 so we must add 1 to comply with the API specification. |
1849 "cast(\"args\".\"number\" + 1 as int) AS \"ORDINAL_POSITION\", " + | 1849 "cast(a.\"number\" + 1 as int) AS \"ORDINAL_POSITION\", " + |
1850 "cast('' as varchar(3)) AS \"IS_NULLABLE\", " + | 1850 "cast('' as varchar(3)) AS \"IS_NULLABLE\", " + |
1851 // the specific name contains the function id, in order to be able to match the args to the correct overloaded procedure name | 1851 // the specific name contains the function id, in order to be able to match the args to the correct overloaded procedure name |
1852 "cast(\"functions\".\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + | 1852 "cast(f.\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + |
1853 "FROM \"sys\".\"args\" " + | 1853 "FROM \"sys\".\"args\" a " + |
1854 "JOIN \"sys\".\"functions\" ON (\"args\".\"func_id\" = \"functions\".\"id\") " + | 1854 "JOIN \"sys\".\"functions\" f ON (a.\"func_id\" = f.\"id\") " + |
1855 "JOIN \"sys\".\"schemas\" ON (\"functions\".\"schema_id\" = \"schemas\".\"id\") " + | 1855 "JOIN \"sys\".\"schemas\" s ON (f.\"schema_id\" = s.\"id\") " + |
1856 // include procedures only (type = 2). Others will be returned via getFunctionColumns() | 1856 // include procedures only (type = 2). Others will be returned via getFunctionColumns() |
1857 "WHERE \"functions\".\"type\" = 2"); | 1857 "WHERE f.\"type\" = 2"); |
1858 | 1858 |
1859 if (catalog != null && !catalog.isEmpty()) { | 1859 if (catalog != null && !catalog.isEmpty()) { |
1860 // non-empty catalog selection. | 1860 // non-empty catalog selection. |
1861 // as we do not support catalogs this always results in no rows returned | 1861 // as we do not support catalogs this always results in no rows returned |
1862 query.append(" AND 1 = 0"); | 1862 query.append(" AND 1 = 0"); |
1863 } else { | 1863 } else { |
1864 if (schemaPattern != null) { | 1864 if (schemaPattern != null) { |
1865 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 1865 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
1866 } | 1866 } |
1867 if (procedureNamePattern != null) { | 1867 if (procedureNamePattern != null) { |
1868 query.append(" AND \"functions\".\"name\" ").append(composeMatchPart(procedureNamePattern)); | 1868 query.append(" AND f.\"name\" ").append(composeMatchPart(procedureNamePattern)); |
1869 } | 1869 } |
1870 if (columnNamePattern != null) { | 1870 if (columnNamePattern != null) { |
1871 query.append(" AND \"args\".\"name\" ").append(composeMatchPart(columnNamePattern)); | 1871 query.append(" AND a.\"name\" ").append(composeMatchPart(columnNamePattern)); |
1872 } | 1872 } |
1873 } | 1873 } |
1874 | 1874 |
1875 query.append(" ORDER BY \"PROCEDURE_SCHEM\", \"PROCEDURE_NAME\", \"SPECIFIC_NAME\", \"ORDINAL_POSITION\""); | 1875 query.append(" ORDER BY \"PROCEDURE_SCHEM\", \"PROCEDURE_NAME\", \"SPECIFIC_NAME\", \"ORDINAL_POSITION\""); |
1876 | 1876 |
1971 if (preJul2015 && types != null && types.length > 0) { | 1971 if (preJul2015 && types != null && types.length > 0) { |
1972 // we need to filter on the constructed "TABLE_TYPE" expression, this is only possible when we use a subquery in the FROM | 1972 // we need to filter on the constructed "TABLE_TYPE" expression, this is only possible when we use a subquery in the FROM |
1973 query.append("SELECT * FROM ("); | 1973 query.append("SELECT * FROM ("); |
1974 } | 1974 } |
1975 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 1975 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
1976 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 1976 "s.\"name\" AS \"TABLE_SCHEM\", " + |
1977 "\"tables\".\"name\" AS \"TABLE_NAME\", "); | 1977 "t.\"name\" AS \"TABLE_NAME\", "); |
1978 if (preJul2015) { | 1978 if (preJul2015) { |
1979 query.append( | 1979 query.append( |
1980 "CASE WHEN \"tables\".\"system\" = true AND \"tables\".\"type\" IN (0, 10) AND \"tables\".\"temporary\" = 0 THEN 'SYSTEM TABLE' " + | 1980 "CASE WHEN t.\"system\" = true AND t.\"type\" IN (0, 10) AND t.\"temporary\" = 0 THEN 'SYSTEM TABLE' " + |
1981 "WHEN \"tables\".\"system\" = true AND \"tables\".\"type\" IN (1, 11) AND \"tables\".\"temporary\" = 0 THEN 'SYSTEM VIEW' " + | 1981 "WHEN t.\"system\" = true AND t.\"type\" IN (1, 11) AND t.\"temporary\" = 0 THEN 'SYSTEM VIEW' " + |
1982 "WHEN \"tables\".\"system\" = false AND \"tables\".\"type\" = 0 AND \"tables\".\"temporary\" = 0 THEN 'TABLE' " + | 1982 "WHEN t.\"system\" = false AND t.\"type\" = 0 AND t.\"temporary\" = 0 THEN 'TABLE' " + |
1983 "WHEN \"tables\".\"system\" = false AND \"tables\".\"type\" = 1 AND \"tables\".\"temporary\" = 0 THEN 'VIEW' " + | 1983 "WHEN t.\"system\" = false AND t.\"type\" = 1 AND t.\"temporary\" = 0 THEN 'VIEW' " + |
1984 "WHEN \"tables\".\"system\" = true AND \"tables\".\"type\" IN (0, 20) AND \"tables\".\"temporary\" = 1 THEN 'SYSTEM SESSION TABLE' " + | 1984 "WHEN t.\"system\" = true AND t.\"type\" IN (0, 20) AND t.\"temporary\" = 1 THEN 'SYSTEM SESSION TABLE' " + |
1985 "WHEN \"tables\".\"system\" = true AND \"tables\".\"type\" IN (1, 21) AND \"tables\".\"temporary\" = 1 THEN 'SYSTEM SESSION VIEW' " + | 1985 "WHEN t.\"system\" = true AND t.\"type\" IN (1, 21) AND t.\"temporary\" = 1 THEN 'SYSTEM SESSION VIEW' " + |
1986 "WHEN \"tables\".\"system\" = false AND \"tables\".\"type\" IN (0, 30) AND \"tables\".\"temporary\" = 1 THEN 'SESSION TABLE' " + | 1986 "WHEN t.\"system\" = false AND t.\"type\" IN (0, 30) AND t.\"temporary\" = 1 THEN 'SESSION TABLE' " + |
1987 "WHEN \"tables\".\"system\" = false AND \"tables\".\"type\" IN (1, 31) AND \"tables\".\"temporary\" = 1 THEN 'SESSION VIEW' " + | 1987 "WHEN t.\"system\" = false AND t.\"type\" IN (1, 31) AND t.\"temporary\" = 1 THEN 'SESSION VIEW' " + |
1988 "END AS \"TABLE_TYPE\", "); | 1988 "END AS \"TABLE_TYPE\", "); |
1989 } else { | 1989 } else { |
1990 query.append("\"table_types\".\"table_type_name\" AS \"TABLE_TYPE\", "); | 1990 query.append("tt.\"table_type_name\" AS \"TABLE_TYPE\", "); |
1991 } | 1991 } |
1992 query.append(useCommentsTable ? "COALESCE(\"comments\".\"remark\", \"tables\".\"query\")" : "\"tables\".\"query\"").append(" AS \"REMARKS\", " + | 1992 query.append(useCommentsTable ? "COALESCE(cm.\"remark\", t.\"query\")" : "t.\"query\"").append(" AS \"REMARKS\", " + |
1993 "cast(null as char(1)) AS \"TYPE_CAT\", " + | 1993 "cast(null as char(1)) AS \"TYPE_CAT\", " + |
1994 "cast(null as char(1)) AS \"TYPE_SCHEM\", " + | 1994 "cast(null as char(1)) AS \"TYPE_SCHEM\", " + |
1995 "cast(null as char(1)) AS \"TYPE_NAME\", " + | 1995 "cast(null as char(1)) AS \"TYPE_NAME\", " + |
1996 "cast(null as char(1)) AS \"SELF_REFERENCING_COL_NAME\", " + | 1996 "cast(null as char(1)) AS \"SELF_REFERENCING_COL_NAME\", " + |
1997 "cast(null as char(1)) AS \"REF_GENERATION\" " + | 1997 "cast(null as char(1)) AS \"REF_GENERATION\" " + |
1998 "FROM \"sys\".\"tables\""); | 1998 "FROM \"sys\".\"tables\" t "); |
1999 if (!preJul2015) { | |
2000 query.append("JOIN \"sys\".\"table_types\" tt ON t.\"type\" = tt.\"table_type_id\" "); | |
2001 } | |
2002 query.append("JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" "); | |
1999 if (useCommentsTable) { | 2003 if (useCommentsTable) { |
2000 query.append(" LEFT OUTER JOIN \"sys\".\"comments\" ON (\"tables\".\"id\" = \"comments\".\"id\")"); | 2004 query.append("LEFT OUTER JOIN \"sys\".\"comments\" cm ON t.\"id\" = cm.\"id\" "); |
2001 } | 2005 } |
2002 query.append(", \"sys\".\"schemas\""); | 2006 query.append("WHERE 1 = 1"); |
2003 if (!preJul2015) { | |
2004 query.append(", \"sys\".\"table_types\""); | |
2005 } | |
2006 query.append(" WHERE \"tables\".\"schema_id\" = \"schemas\".\"id\""); | |
2007 if (!preJul2015) { | |
2008 query.append(" AND \"tables\".\"type\" = \"table_types\".\"table_type_id\""); | |
2009 } | |
2010 | 2007 |
2011 if (catalog != null && !catalog.isEmpty()) { | 2008 if (catalog != null && !catalog.isEmpty()) { |
2012 // non-empty catalog selection. | 2009 // non-empty catalog selection. |
2013 // as we do not support catalogs this always results in no rows returned | 2010 // as we do not support catalogs this always results in no rows returned |
2014 query.append(" AND 1 = 0"); | 2011 query.append(" AND 1 = 0"); |
2015 } else { | 2012 } else { |
2016 if (schemaPattern != null) { | 2013 if (schemaPattern != null) { |
2017 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 2014 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
2018 } | 2015 } |
2019 if (tableNamePattern != null) { | 2016 if (tableNamePattern != null) { |
2020 query.append(" AND \"tables\".\"name\" ").append(composeMatchPart(tableNamePattern)); | 2017 query.append(" AND t.\"name\" ").append(composeMatchPart(tableNamePattern)); |
2021 } | 2018 } |
2022 } | 2019 } |
2023 | 2020 |
2024 if (types != null && types.length > 0) { | 2021 if (types != null && types.length > 0) { |
2025 if (preJul2015) { | 2022 if (preJul2015) { |
2026 query.append(") AS \"getTables\" WHERE \"TABLE_TYPE\" IN ("); | 2023 query.append(") AS \"getTables\" WHERE \"TABLE_TYPE\" IN ("); |
2027 } else { | 2024 } else { |
2028 query.append(" AND \"table_types\".\"table_type_name\" IN ("); | 2025 query.append(" AND tt.\"table_type_name\" IN ("); |
2029 } | 2026 } |
2030 for (int i = 0; i < types.length; i++) { | 2027 for (int i = 0; i < types.length; i++) { |
2031 if (i > 0) { | 2028 if (i > 0) { |
2032 query.append(", "); | 2029 query.append(", "); |
2033 } | 2030 } |
2220 ) throws SQLException | 2217 ) throws SQLException |
2221 { | 2218 { |
2222 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); | 2219 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); |
2223 final StringBuilder query = new StringBuilder(2450); | 2220 final StringBuilder query = new StringBuilder(2450); |
2224 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 2221 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
2225 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2222 "s.\"name\" AS \"TABLE_SCHEM\", " + |
2226 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2223 "t.\"name\" AS \"TABLE_NAME\", " + |
2227 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + | 2224 "c.\"name\" AS \"COLUMN_NAME\", " + |
2228 "cast(").append(MonetDriver.getSQLTypeMap("\"columns\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + | 2225 "cast(").append(MonetDriver.getSQLTypeMap("c.\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + |
2229 "\"columns\".\"type\" AS \"TYPE_NAME\", " + | 2226 "c.\"type\" AS \"TYPE_NAME\", " + |
2230 "\"columns\".\"type_digits\" AS \"COLUMN_SIZE\", " + | 2227 "c.\"type_digits\" AS \"COLUMN_SIZE\", " + |
2231 "0 AS \"BUFFER_LENGTH\", " + | 2228 "0 AS \"BUFFER_LENGTH\", " + |
2232 "\"columns\".\"type_scale\" AS \"DECIMAL_DIGITS\", " + | 2229 "c.\"type_scale\" AS \"DECIMAL_DIGITS\", " + |
2233 "cast(CASE WHEN \"columns\".\"type\" IN ('decimal', 'numeric', 'sec_interval') THEN 10 " + | 2230 "cast(CASE WHEN c.\"type\" IN ('decimal', 'numeric', 'sec_interval') THEN 10 " + |
2234 "WHEN \"columns\".\"type\" IN ('int', 'smallint', 'tinyint', 'bigint', 'hugeint', 'float', 'real', 'double', 'oid', 'wrd') THEN 2 " + | 2231 "WHEN c.\"type\" IN ('int', 'smallint', 'tinyint', 'bigint', 'hugeint', 'float', 'real', 'double', 'oid', 'wrd') THEN 2 " + |
2235 "ELSE 0 END AS int) AS \"NUM_PREC_RADIX\", " + | 2232 "ELSE 0 END AS int) AS \"NUM_PREC_RADIX\", " + |
2236 "cast(CASE \"null\" WHEN true THEN ").append(ResultSetMetaData.columnNullable) | 2233 "cast(CASE c.\"null\" WHEN true THEN ").append(ResultSetMetaData.columnNullable) |
2237 .append(" WHEN false THEN ").append(ResultSetMetaData.columnNoNulls).append(" END AS int) AS \"NULLABLE\", ") | 2234 .append(" WHEN false THEN ").append(ResultSetMetaData.columnNoNulls).append(" END AS int) AS \"NULLABLE\", ") |
2238 .append(useCommentsTable ? "\"comments\".\"remark\"" : "cast(null AS varchar(9999))").append(" AS \"REMARKS\", " + | 2235 .append(useCommentsTable ? "cm.\"remark\"" : "cast(null AS varchar(9999))").append(" AS \"REMARKS\", " + |
2239 "\"columns\".\"default\" AS \"COLUMN_DEF\", " + | 2236 "c.\"default\" AS \"COLUMN_DEF\", " + |
2240 "cast(0 as int) AS \"SQL_DATA_TYPE\", " + | 2237 "cast(0 as int) AS \"SQL_DATA_TYPE\", " + |
2241 "cast(0 as int) AS \"SQL_DATETIME_SUB\", " + | 2238 "cast(0 as int) AS \"SQL_DATETIME_SUB\", " + |
2242 "cast(CASE WHEN \"columns\".\"type\" IN ('char','varchar','clob') THEN \"columns\".\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " + | 2239 "cast(CASE WHEN c.\"type\" IN ('char','varchar','clob') THEN c.\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " + |
2243 "cast(\"columns\".\"number\" + 1 as int) AS \"ORDINAL_POSITION\", " + | 2240 "cast(c.\"number\" + 1 as int) AS \"ORDINAL_POSITION\", " + |
2244 "cast(CASE \"null\" WHEN true THEN 'YES' WHEN false THEN 'NO' ELSE '' END AS varchar(3)) AS \"IS_NULLABLE\", " + | 2241 "cast(CASE c.\"null\" WHEN true THEN 'YES' WHEN false THEN 'NO' ELSE '' END AS varchar(3)) AS \"IS_NULLABLE\", " + |
2245 "cast(null AS char(1)) AS \"SCOPE_CATALOG\", " + | 2242 "cast(null AS char(1)) AS \"SCOPE_CATALOG\", " + |
2246 "cast(null AS char(1)) AS \"SCOPE_SCHEMA\", " + | 2243 "cast(null AS char(1)) AS \"SCOPE_SCHEMA\", " + |
2247 "cast(null AS char(1)) AS \"SCOPE_TABLE\", " + | 2244 "cast(null AS char(1)) AS \"SCOPE_TABLE\", " + |
2248 "cast(null AS smallint) AS \"SOURCE_DATA_TYPE\", " + | 2245 "cast(null AS smallint) AS \"SOURCE_DATA_TYPE\", " + |
2249 "cast(CASE WHEN \"columns\".\"default\" IS NOT NULL AND \"columns\".\"default\" LIKE 'next value for %' THEN 'YES' ELSE 'NO' END AS varchar(3)) AS \"IS_AUTOINCREMENT\", " + | 2246 "cast(CASE WHEN c.\"default\" IS NOT NULL AND c.\"default\" LIKE 'next value for %' THEN 'YES' ELSE 'NO' END AS varchar(3)) AS \"IS_AUTOINCREMENT\", " + |
2250 "cast('NO' AS varchar(3)) AS \"IS_GENERATEDCOLUMN\" " + | 2247 "cast('NO' AS varchar(3)) AS \"IS_GENERATEDCOLUMN\" " + |
2251 "FROM \"sys\".\"columns\""); | 2248 "FROM \"sys\".\"columns\" c " + |
2249 "JOIN \"sys\".\"tables\" t ON c.\"table_id\" = t.\"id\" " + | |
2250 "JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" "); | |
2252 if (useCommentsTable) { | 2251 if (useCommentsTable) { |
2253 query.append(" LEFT OUTER JOIN \"sys\".\"comments\" ON (\"columns\".\"id\" = \"comments\".\"id\")"); | 2252 query.append("LEFT OUTER JOIN \"sys\".\"comments\" cm ON c.\"id\" = cm.\"id\" "); |
2254 } | 2253 } |
2255 query.append(", \"sys\".\"tables\"" + | 2254 query.append("WHERE 1 = 1"); |
2256 ", \"sys\".\"schemas\" " + | |
2257 "WHERE \"columns\".\"table_id\" = \"tables\".\"id\"" + | |
2258 " AND \"tables\".\"schema_id\" = \"schemas\".\"id\""); | |
2259 | 2255 |
2260 if (catalog != null && !catalog.isEmpty()) { | 2256 if (catalog != null && !catalog.isEmpty()) { |
2261 // non-empty catalog selection. | 2257 // non-empty catalog selection. |
2262 // as we do not support catalogs this always results in no rows returned | 2258 // as we do not support catalogs this always results in no rows returned |
2263 query.append(" AND 1 = 0"); | 2259 query.append(" AND 1 = 0"); |
2264 } else { | 2260 } else { |
2265 if (schemaPattern != null) { | 2261 if (schemaPattern != null) { |
2266 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 2262 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
2267 } | 2263 } |
2268 if (tableNamePattern != null) { | 2264 if (tableNamePattern != null) { |
2269 query.append(" AND \"tables\".\"name\" ").append(composeMatchPart(tableNamePattern)); | 2265 query.append(" AND t.\"name\" ").append(composeMatchPart(tableNamePattern)); |
2270 } | 2266 } |
2271 if (columnNamePattern != null) { | 2267 if (columnNamePattern != null) { |
2272 query.append(" AND \"columns\".\"name\" ").append(composeMatchPart(columnNamePattern)); | 2268 query.append(" AND c.\"name\" ").append(composeMatchPart(columnNamePattern)); |
2273 } | 2269 } |
2274 } | 2270 } |
2275 | 2271 |
2276 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"ORDINAL_POSITION\""); | 2272 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"ORDINAL_POSITION\""); |
2277 | 2273 |
2318 ) throws SQLException | 2314 ) throws SQLException |
2319 { | 2315 { |
2320 final boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); | 2316 final boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); |
2321 final StringBuilder query = new StringBuilder(1100); | 2317 final StringBuilder query = new StringBuilder(1100); |
2322 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 2318 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
2323 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2319 "s.\"name\" AS \"TABLE_SCHEM\", " + |
2324 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2320 "t.\"name\" AS \"TABLE_NAME\", " + |
2325 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + | 2321 "c.\"name\" AS \"COLUMN_NAME\", " + |
2326 "\"grantors\".\"name\" AS \"GRANTOR\", " + | 2322 "grantors.\"name\" AS \"GRANTOR\", " + |
2327 "\"grantees\".\"name\" AS \"GRANTEE\", ") | 2323 "grantees.\"name\" AS \"GRANTEE\", ") |
2328 .append(usePrivilege_codesTable ? "\"privilege_codes\".\"privilege_code_name\"" : | 2324 .append(usePrivilege_codesTable ? "pc.\"privilege_code_name\"" : |
2329 "cast(CASE \"privileges\".\"privileges\" " + | 2325 "cast(CASE p.\"privileges\" " + |
2330 "WHEN 1 THEN 'SELECT' " + | 2326 "WHEN 1 THEN 'SELECT' " + |
2331 "WHEN 2 THEN 'UPDATE' " + | 2327 "WHEN 2 THEN 'UPDATE' " + |
2332 "WHEN 4 THEN 'INSERT' " + | 2328 "WHEN 4 THEN 'INSERT' " + |
2333 "WHEN 8 THEN 'DELETE' " + | 2329 "WHEN 8 THEN 'DELETE' " + |
2334 "WHEN 16 THEN 'EXECUTE' " + | 2330 "WHEN 16 THEN 'EXECUTE' " + |
2335 "WHEN 32 THEN 'GRANT' " + | 2331 "WHEN 32 THEN 'GRANT' " + |
2336 "ELSE NULL " + | 2332 "ELSE NULL " + |
2337 "END AS varchar(7))").append(" AS \"PRIVILEGE\", " + | 2333 "END AS varchar(7))").append(" AS \"PRIVILEGE\", " + |
2338 "cast(CASE \"privileges\".\"grantable\" " + | 2334 "cast(CASE p.\"grantable\" " + |
2339 "WHEN 0 THEN 'NO' " + | 2335 "WHEN 0 THEN 'NO' " + |
2340 "WHEN 1 THEN 'YES' " + | 2336 "WHEN 1 THEN 'YES' " + |
2341 "ELSE NULL " + | 2337 "ELSE NULL " + |
2342 "END AS varchar(3)) AS \"IS_GRANTABLE\" " + | 2338 "END AS varchar(3)) AS \"IS_GRANTABLE\" " + |
2343 "FROM \"sys\".\"privileges\", " + | 2339 "FROM \"sys\".\"privileges\" p " + |
2344 "\"sys\".\"tables\", " + | 2340 "JOIN \"sys\".\"columns\" c ON p.\"obj_id\" = c.\"id\" " + |
2345 "\"sys\".\"schemas\", " + | 2341 "JOIN \"sys\".\"tables\" t ON c.\"table_id\" = t.\"id\" " + |
2346 "\"sys\".\"columns\", " + | 2342 "JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" " + |
2347 "\"sys\".\"auths\" AS \"grantors\", " + | 2343 "JOIN \"sys\".\"auths\" grantors ON p.\"grantor\" = grantors.\"id\" " + |
2348 "\"sys\".\"auths\" AS \"grantees\" "); | 2344 "JOIN \"sys\".\"auths\" grantees ON p.\"auth_id\" = grantees.\"id\" "); |
2349 if (usePrivilege_codesTable) { | 2345 if (usePrivilege_codesTable) { |
2350 query.append(", \"sys\".\"privilege_codes\" "); | 2346 query.append("JOIN \"sys\".\"privilege_codes\" pc ON p.\"privileges\" = pc.\"privilege_code_id\" "); |
2351 } | 2347 } |
2352 query.append("WHERE \"privileges\".\"obj_id\" = \"columns\".\"id\" " + | 2348 query.append("WHERE 1 = 1"); |
2353 "AND \"columns\".\"table_id\" = \"tables\".\"id\" " + | |
2354 "AND \"tables\".\"schema_id\" = \"schemas\".\"id\" " + | |
2355 "AND \"privileges\".\"auth_id\" = \"grantees\".\"id\" " + | |
2356 "AND \"privileges\".\"grantor\" = \"grantors\".\"id\""); | |
2357 if (usePrivilege_codesTable) { | |
2358 query.append(" AND \"privileges\".\"privileges\" = \"privilege_codes\".\"privilege_code_id\""); | |
2359 } | |
2360 | 2349 |
2361 if (catalog != null && !catalog.isEmpty()) { | 2350 if (catalog != null && !catalog.isEmpty()) { |
2362 // non-empty catalog selection. | 2351 // non-empty catalog selection. |
2363 // as we do not support catalogs this always results in no rows returned | 2352 // as we do not support catalogs this always results in no rows returned |
2364 query.append(" AND 1 = 0"); | 2353 query.append(" AND 1 = 0"); |
2365 } else { | 2354 } else { |
2366 if (schemaPattern != null) { | 2355 if (schemaPattern != null) { |
2367 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 2356 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
2368 } | 2357 } |
2369 if (tableNamePattern != null) { | 2358 if (tableNamePattern != null) { |
2370 query.append(" AND \"tables\".\"name\" ").append(composeMatchPart(tableNamePattern)); | 2359 query.append(" AND t.\"name\" ").append(composeMatchPart(tableNamePattern)); |
2371 } | 2360 } |
2372 if (columnNamePattern != null) { | 2361 if (columnNamePattern != null) { |
2373 query.append(" AND \"columns\".\"name\" ").append(composeMatchPart(columnNamePattern)); | 2362 query.append(" AND c.\"name\" ").append(composeMatchPart(columnNamePattern)); |
2374 } | 2363 } |
2375 } | 2364 } |
2376 | 2365 |
2377 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"COLUMN_NAME\", \"PRIVILEGE\""); | 2366 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"COLUMN_NAME\", \"PRIVILEGE\""); |
2378 | 2367 |
2416 ) throws SQLException | 2405 ) throws SQLException |
2417 { | 2406 { |
2418 final boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); | 2407 final boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); |
2419 final StringBuilder query = new StringBuilder(1000); | 2408 final StringBuilder query = new StringBuilder(1000); |
2420 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 2409 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
2421 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2410 "s.\"name\" AS \"TABLE_SCHEM\", " + |
2422 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2411 "t.\"name\" AS \"TABLE_NAME\", " + |
2423 "\"grantors\".\"name\" AS \"GRANTOR\", " + | 2412 "grantors.\"name\" AS \"GRANTOR\", " + |
2424 "\"grantees\".\"name\" AS \"GRANTEE\", ") | 2413 "grantees.\"name\" AS \"GRANTEE\", ") |
2425 .append(usePrivilege_codesTable ? "\"privilege_codes\".\"privilege_code_name\"" : | 2414 .append(usePrivilege_codesTable ? "pc.\"privilege_code_name\"" : |
2426 "cast(CASE \"privileges\".\"privileges\" " + | 2415 "cast(CASE p.\"privileges\" " + |
2427 "WHEN 1 THEN 'SELECT' " + | 2416 "WHEN 1 THEN 'SELECT' " + |
2428 "WHEN 2 THEN 'UPDATE' " + | 2417 "WHEN 2 THEN 'UPDATE' " + |
2429 "WHEN 4 THEN 'INSERT' " + | 2418 "WHEN 4 THEN 'INSERT' " + |
2430 "WHEN 8 THEN 'DELETE' " + | 2419 "WHEN 8 THEN 'DELETE' " + |
2431 "WHEN 16 THEN 'EXECUTE' " + | 2420 "WHEN 16 THEN 'EXECUTE' " + |
2432 "WHEN 32 THEN 'GRANT' " + | 2421 "WHEN 32 THEN 'GRANT' " + |
2433 "ELSE NULL " + | 2422 "ELSE NULL " + |
2434 "END AS varchar(7))").append(" AS \"PRIVILEGE\", " + | 2423 "END AS varchar(7))").append(" AS \"PRIVILEGE\", " + |
2435 "cast(CASE \"privileges\".\"grantable\" " + | 2424 "cast(CASE p.\"grantable\" " + |
2436 "WHEN 0 THEN 'NO' " + | 2425 "WHEN 0 THEN 'NO' " + |
2437 "WHEN 1 THEN 'YES' " + | 2426 "WHEN 1 THEN 'YES' " + |
2438 "ELSE NULL " + | 2427 "ELSE NULL " + |
2439 "END AS varchar(3)) AS \"IS_GRANTABLE\" " + | 2428 "END AS varchar(3)) AS \"IS_GRANTABLE\" " + |
2440 "FROM \"sys\".\"privileges\", " + | 2429 "FROM \"sys\".\"privileges\" p " + |
2441 "\"sys\".\"tables\", " + | 2430 "JOIN \"sys\".\"tables\" t ON p.\"obj_id\" = t.\"id\" " + |
2442 "\"sys\".\"schemas\", " + | 2431 "JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" " + |
2443 "\"sys\".\"auths\" AS \"grantors\", " + | 2432 "JOIN \"sys\".\"auths\" grantors ON p.\"grantor\" = grantors.\"id\" " + |
2444 "\"sys\".\"auths\" AS \"grantees\" "); | 2433 "JOIN \"sys\".\"auths\" grantees ON p.\"auth_id\" = grantees.\"id\" "); |
2445 if (usePrivilege_codesTable) { | 2434 if (usePrivilege_codesTable) { |
2446 query.append(", \"sys\".\"privilege_codes\" "); | 2435 query.append("JOIN \"sys\".\"privilege_codes\" pc ON p.\"privileges\" = pc.\"privilege_code_id\" "); |
2447 } | 2436 } |
2448 query.append("WHERE \"privileges\".\"obj_id\" = \"tables\".\"id\" " + | 2437 query.append("WHERE 1 = 1"); |
2449 "AND \"tables\".\"schema_id\" = \"schemas\".\"id\" " + | |
2450 "AND \"privileges\".\"auth_id\" = \"grantees\".\"id\" " + | |
2451 "AND \"privileges\".\"grantor\" = \"grantors\".\"id\""); | |
2452 if (usePrivilege_codesTable) { | |
2453 query.append(" AND \"privileges\".\"privileges\" = \"privilege_codes\".\"privilege_code_id\""); | |
2454 } | |
2455 | 2438 |
2456 if (catalog != null && !catalog.isEmpty()) { | 2439 if (catalog != null && !catalog.isEmpty()) { |
2457 // non-empty catalog selection. | 2440 // non-empty catalog selection. |
2458 // as we do not support catalogs this always results in no rows returned | 2441 // as we do not support catalogs this always results in no rows returned |
2459 query.append(" AND 1 = 0"); | 2442 query.append(" AND 1 = 0"); |
2460 } else { | 2443 } else { |
2461 if (schemaPattern != null) { | 2444 if (schemaPattern != null) { |
2462 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 2445 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
2463 } | 2446 } |
2464 if (tableNamePattern != null) { | 2447 if (tableNamePattern != null) { |
2465 query.append(" AND \"tables\".\"name\" ").append(composeMatchPart(tableNamePattern)); | 2448 query.append(" AND t.\"name\" ").append(composeMatchPart(tableNamePattern)); |
2466 } | 2449 } |
2467 } | 2450 } |
2468 | 2451 |
2469 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"PRIVILEGE\""); | 2452 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"PRIVILEGE\""); |
2470 | 2453 |
2516 final boolean nullable | 2499 final boolean nullable |
2517 ) throws SQLException | 2500 ) throws SQLException |
2518 { | 2501 { |
2519 final StringBuilder query = new StringBuilder(1500); | 2502 final StringBuilder query = new StringBuilder(1500); |
2520 query.append("SELECT cast(").append(DatabaseMetaData.bestRowSession).append(" AS smallint) AS \"SCOPE\", " + | 2503 query.append("SELECT cast(").append(DatabaseMetaData.bestRowSession).append(" AS smallint) AS \"SCOPE\", " + |
2521 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + | 2504 "c.\"name\" AS \"COLUMN_NAME\", " + |
2522 "cast(").append(MonetDriver.getSQLTypeMap("\"columns\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + | 2505 "cast(").append(MonetDriver.getSQLTypeMap("c.\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + |
2523 "\"columns\".\"type\" AS \"TYPE_NAME\", " + | 2506 "c.\"type\" AS \"TYPE_NAME\", " + |
2524 "\"columns\".\"type_digits\" AS \"COLUMN_SIZE\", " + | 2507 "c.\"type_digits\" AS \"COLUMN_SIZE\", " + |
2525 "cast(0 as int) AS \"BUFFER_LENGTH\", " + | 2508 "cast(0 as int) AS \"BUFFER_LENGTH\", " + |
2526 "cast(\"columns\".\"type_scale\" AS smallint) AS \"DECIMAL_DIGITS\", " + | 2509 "cast(c.\"type_scale\" AS smallint) AS \"DECIMAL_DIGITS\", " + |
2527 "cast(").append(DatabaseMetaData.bestRowNotPseudo).append(" AS smallint) AS \"PSEUDO_COLUMN\" " + | 2510 "cast(").append(DatabaseMetaData.bestRowNotPseudo).append(" AS smallint) AS \"PSEUDO_COLUMN\" " + |
2528 "FROM \"sys\".\"keys\", " + | 2511 "FROM \"sys\".\"keys\" k " + |
2529 "\"sys\".\"objects\", " + | 2512 "JOIN \"sys\".\"objects\" o ON k.\"id\" = o.\"id\" " + |
2530 "\"sys\".\"columns\", " + | 2513 "JOIN \"sys\".\"columns\" c ON (k.\"table_id\" = c.\"table_id\" AND o.\"name\" = c.\"name\") " + |
2531 "\"sys\".\"tables\", " + | 2514 "JOIN \"sys\".\"tables\" t ON k.\"table_id\" = t.\"id\" " + |
2532 "\"sys\".\"schemas\" " + | 2515 "JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" " + |
2533 "WHERE \"keys\".\"id\" = \"objects\".\"id\" " + | 2516 "WHERE k.\"type\" IN (0, 1)"); // only primary keys (type = 0) and unique keys (type = 1), not fkeys (type = 2) |
2534 "AND \"keys\".\"table_id\" = \"tables\".\"id\" " + | |
2535 "AND \"keys\".\"table_id\" = \"columns\".\"table_id\" " + | |
2536 "AND \"objects\".\"name\" = \"columns\".\"name\" " + | |
2537 "AND \"tables\".\"schema_id\" = \"schemas\".\"id\" " + | |
2538 "AND \"keys\".\"type\" IN (0, 1)"); // only primary keys (type = 0) and unique keys (type = 1), not fkeys (type = 2) | |
2539 | 2517 |
2540 if (catalog != null && !catalog.isEmpty()) { | 2518 if (catalog != null && !catalog.isEmpty()) { |
2541 // non-empty catalog selection. | 2519 // non-empty catalog selection. |
2542 // as we do not support catalogs this always results in no rows returned | 2520 // as we do not support catalogs this always results in no rows returned |
2543 query.append(" AND 1 = 0"); | 2521 query.append(" AND 1 = 0"); |
2546 && scope != DatabaseMetaData.bestRowTransaction | 2524 && scope != DatabaseMetaData.bestRowTransaction |
2547 && scope != DatabaseMetaData.bestRowTemporary) { | 2525 && scope != DatabaseMetaData.bestRowTemporary) { |
2548 query.append(" AND 1 = 0"); | 2526 query.append(" AND 1 = 0"); |
2549 } else { | 2527 } else { |
2550 if (schema != null) { | 2528 if (schema != null) { |
2551 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schema)); | 2529 query.append(" AND s.\"name\" ").append(composeMatchPart(schema)); |
2552 } | 2530 } |
2553 if (table != null) { | 2531 if (table != null) { |
2554 query.append(" AND \"tables\".\"name\" ").append(composeMatchPart(table)); | 2532 query.append(" AND t.\"name\" ").append(composeMatchPart(table)); |
2555 } | 2533 } |
2556 if (!nullable) { | 2534 if (!nullable) { |
2557 query.append(" AND \"columns\".\"null\" = false"); | 2535 query.append(" AND c.\"null\" = false"); |
2558 } | 2536 } |
2559 } | 2537 } |
2560 } | 2538 } |
2561 | 2539 |
2562 query.append(" ORDER BY \"keys\".\"type\", \"columns\".\"name\""); | 2540 query.append(" ORDER BY k.\"type\", c.\"name\""); |
2563 | 2541 |
2564 return executeMetaDataQuery(query.toString()); | 2542 return executeMetaDataQuery(query.toString()); |
2565 } | 2543 } |
2566 | 2544 |
2567 /** | 2545 /** |
2642 final String table | 2620 final String table |
2643 ) throws SQLException | 2621 ) throws SQLException |
2644 { | 2622 { |
2645 final StringBuilder query = new StringBuilder(600); | 2623 final StringBuilder query = new StringBuilder(600); |
2646 query.append("SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + | 2624 query.append("SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + |
2647 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2625 "s.\"name\" AS \"TABLE_SCHEM\", " + |
2648 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2626 "t.\"name\" AS \"TABLE_NAME\", " + |
2649 "\"objects\".\"name\" AS \"COLUMN_NAME\", " + | 2627 "o.\"name\" AS \"COLUMN_NAME\", " + |
2650 "cast(1 + \"objects\".\"nr\" AS smallint) AS \"KEY_SEQ\", " + | 2628 "cast(1 + o.\"nr\" AS smallint) AS \"KEY_SEQ\", " + |
2651 " \"keys\".\"name\" AS \"PK_NAME\" " + | 2629 " k.\"name\" AS \"PK_NAME\" " + |
2652 "FROM \"sys\".\"keys\", " + | 2630 "FROM \"sys\".\"keys\" k " + |
2653 "\"sys\".\"objects\", " + | 2631 "JOIN \"sys\".\"objects\" o ON k.\"id\" = o.\"id\" " + |
2654 "\"sys\".\"tables\", " + | 2632 "JOIN \"sys\".\"tables\" t ON k.\"table_id\" = t.\"id\" " + |
2655 "\"sys\".\"schemas\" " + | 2633 "JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" " + |
2656 "WHERE \"keys\".\"id\" = \"objects\".\"id\" " + | 2634 "WHERE k.\"type\" = 0"); // only primary keys (type = 0) |
2657 "AND \"keys\".\"table_id\" = \"tables\".\"id\" " + | |
2658 "AND \"tables\".\"schema_id\" = \"schemas\".\"id\" " + | |
2659 "AND \"keys\".\"type\" = 0"); | |
2660 | 2635 |
2661 if (catalog != null && !catalog.isEmpty()) { | 2636 if (catalog != null && !catalog.isEmpty()) { |
2662 // non-empty catalog selection. | 2637 // non-empty catalog selection. |
2663 // as we do not support catalogs this always results in no rows returned | 2638 // as we do not support catalogs this always results in no rows returned |
2664 query.append(" AND 1 = 0"); | 2639 query.append(" AND 1 = 0"); |
2665 } else { | 2640 } else { |
2666 if (schema != null) { | 2641 if (schema != null) { |
2667 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schema)); | 2642 query.append(" AND s.\"name\" ").append(composeMatchPart(schema)); |
2668 } | 2643 } |
2669 if (table != null) { | 2644 if (table != null) { |
2670 query.append(" AND \"tables\".\"name\" ").append(composeMatchPart(table)); | 2645 query.append(" AND t.\"name\" ").append(composeMatchPart(table)); |
2671 } | 2646 } |
2672 } | 2647 } |
2673 | 2648 |
2674 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"COLUMN_NAME\""); | 2649 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"COLUMN_NAME\""); |
2675 | 2650 |
2677 } | 2652 } |
2678 | 2653 |
2679 | 2654 |
2680 private static final String keyQuery = | 2655 private static final String keyQuery = |
2681 "SELECT cast(null AS char(1)) AS \"PKTABLE_CAT\", " + | 2656 "SELECT cast(null AS char(1)) AS \"PKTABLE_CAT\", " + |
2682 "\"pkschema\".\"name\" AS \"PKTABLE_SCHEM\", " + | 2657 "pkschema.\"name\" AS \"PKTABLE_SCHEM\", " + |
2683 "\"pktable\".\"name\" AS \"PKTABLE_NAME\", " + | 2658 "pktable.\"name\" AS \"PKTABLE_NAME\", " + |
2684 "\"pkkeycol\".\"name\" AS \"PKCOLUMN_NAME\", " + | 2659 "pkkeycol.\"name\" AS \"PKCOLUMN_NAME\", " + |
2685 "cast(null AS char(1)) AS \"FKTABLE_CAT\", " + | 2660 "cast(null AS char(1)) AS \"FKTABLE_CAT\", " + |
2686 "\"fkschema\".\"name\" AS \"FKTABLE_SCHEM\", " + | 2661 "fkschema.\"name\" AS \"FKTABLE_SCHEM\", " + |
2687 "\"fktable\".\"name\" AS \"FKTABLE_NAME\", " + | 2662 "fktable.\"name\" AS \"FKTABLE_NAME\", " + |
2688 "\"fkkeycol\".\"name\" AS \"FKCOLUMN_NAME\", " + | 2663 "fkkeycol.\"name\" AS \"FKCOLUMN_NAME\", " + |
2689 "cast(1 + \"pkkeycol\".\"nr\" AS smallint) AS \"KEY_SEQ\", " + | 2664 "cast(1 + \"pkkeycol\".\"nr\" AS smallint) AS \"KEY_SEQ\", " + |
2690 DatabaseMetaData.importedKeyNoAction + " AS \"UPDATE_RULE\", " + | 2665 DatabaseMetaData.importedKeyNoAction + " AS \"UPDATE_RULE\", " + |
2691 DatabaseMetaData.importedKeyNoAction + " AS \"DELETE_RULE\", " + | 2666 DatabaseMetaData.importedKeyNoAction + " AS \"DELETE_RULE\", " + |
2692 "\"fkkey\".\"name\" AS \"FK_NAME\", " + | 2667 "fkkey.\"name\" AS \"FK_NAME\", " + |
2693 "\"pkkey\".\"name\" AS \"PK_NAME\", " + | 2668 "pkkey.\"name\" AS \"PK_NAME\", " + |
2694 DatabaseMetaData.importedKeyNotDeferrable + " AS \"DEFERRABILITY\" " + | 2669 DatabaseMetaData.importedKeyNotDeferrable + " AS \"DEFERRABILITY\" " + |
2695 "FROM \"sys\".\"keys\" AS \"fkkey\", " + | 2670 "FROM \"sys\".\"keys\" pkkey " + |
2696 "\"sys\".\"keys\" AS \"pkkey\", " + | 2671 "JOIN \"sys\".\"objects\" pkkeycol ON pkkey.\"id\" = pkkeycol.\"id\" " + |
2697 "\"sys\".\"objects\" AS \"fkkeycol\", " + | 2672 "JOIN \"sys\".\"tables\" pktable ON pktable.\"id\" = pkkey.\"table_id\" " + |
2698 "\"sys\".\"objects\" AS \"pkkeycol\", " + | 2673 "JOIN \"sys\".\"schemas\" pkschema ON pkschema.\"id\" = pktable.\"schema_id\" " + |
2699 "\"sys\".\"tables\" AS \"fktable\", " + | 2674 "JOIN \"sys\".\"keys\" fkkey ON fkkey.\"rkey\" = pkkey.\"id\" " + |
2700 "\"sys\".\"tables\" AS \"pktable\", " + | 2675 "JOIN \"sys\".\"objects\" fkkeycol ON (fkkey.\"id\" = fkkeycol.\"id\" AND fkkeycol.\"nr\" = pkkeycol.\"nr\") " + |
2701 "\"sys\".\"schemas\" AS \"fkschema\", " + | 2676 "JOIN \"sys\".\"tables\" fktable ON fktable.\"id\" = fkkey.\"table_id\" " + |
2702 "\"sys\".\"schemas\" AS \"pkschema\" " + | 2677 "JOIN \"sys\".\"schemas\" fkschema ON fkschema.\"id\" = fktable.\"schema_id\" " + |
2703 "WHERE \"fktable\".\"id\" = \"fkkey\".\"table_id\"" + | 2678 "WHERE fkkey.\"rkey\" > 0"; // exclude invalid key references, such as -1 |
2704 " AND \"pktable\".\"id\" = \"pkkey\".\"table_id\"" + | |
2705 " AND \"fkkey\".\"id\" = \"fkkeycol\".\"id\"" + | |
2706 " AND \"pkkey\".\"id\" = \"pkkeycol\".\"id\"" + | |
2707 " AND \"fkschema\".\"id\" = \"fktable\".\"schema_id\"" + | |
2708 " AND \"pkschema\".\"id\" = \"pktable\".\"schema_id\"" + | |
2709 " AND \"fkkey\".\"rkey\" > -1" + | |
2710 " AND \"fkkey\".\"rkey\" = \"pkkey\".\"id\"" + | |
2711 " AND \"fkkeycol\".\"nr\" = \"pkkeycol\".\"nr\""; | |
2712 | 2679 |
2713 /** | 2680 /** |
2714 * Get a description of the primary key columns that are | 2681 * Get a description of the primary key columns that are |
2715 * referenced by a table's foreign key columns (the primary keys | 2682 * referenced by a table's foreign key columns (the primary keys |
2716 * imported by a table). They are ordered by PKTABLE_CAT, | 2683 * imported by a table). They are ordered by PKTABLE_CAT, |
2785 // non-empty catalog selection. | 2752 // non-empty catalog selection. |
2786 // as we do not support catalogs this always results in no rows returned | 2753 // as we do not support catalogs this always results in no rows returned |
2787 query.append(" AND 1 = 0"); | 2754 query.append(" AND 1 = 0"); |
2788 } else { | 2755 } else { |
2789 if (schema != null) { | 2756 if (schema != null) { |
2790 query.append(" AND \"fkschema\".\"name\" ").append(composeMatchPart(schema)); | 2757 query.append(" AND fkschema.\"name\" ").append(composeMatchPart(schema)); |
2791 } | 2758 } |
2792 if (table != null) { | 2759 if (table != null) { |
2793 query.append(" AND \"fktable\".\"name\" ").append(composeMatchPart(table)); | 2760 query.append(" AND fktable.\"name\" ").append(composeMatchPart(table)); |
2794 } | 2761 } |
2795 } | 2762 } |
2796 | 2763 |
2797 query.append(" ORDER BY \"PKTABLE_SCHEM\", \"PKTABLE_NAME\", \"PK_NAME\", \"KEY_SEQ\""); | 2764 query.append(" ORDER BY \"PKTABLE_SCHEM\", \"PKTABLE_NAME\", \"PK_NAME\", \"KEY_SEQ\""); |
2798 | 2765 |
2873 // non-empty catalog selection. | 2840 // non-empty catalog selection. |
2874 // as we do not support catalogs this always results in no rows returned | 2841 // as we do not support catalogs this always results in no rows returned |
2875 query.append(" AND 1 = 0"); | 2842 query.append(" AND 1 = 0"); |
2876 } else { | 2843 } else { |
2877 if (schema != null) { | 2844 if (schema != null) { |
2878 query.append(" AND \"pkschema\".\"name\" ").append(composeMatchPart(schema)); | 2845 query.append(" AND pkschema.\"name\" ").append(composeMatchPart(schema)); |
2879 } | 2846 } |
2880 if (table != null) { | 2847 if (table != null) { |
2881 query.append(" AND \"pktable\".\"name\" ").append(composeMatchPart(table)); | 2848 query.append(" AND pktable.\"name\" ").append(composeMatchPart(table)); |
2882 } | 2849 } |
2883 } | 2850 } |
2884 | 2851 |
2885 query.append(" ORDER BY \"FKTABLE_SCHEM\", \"FKTABLE_NAME\", \"FK_NAME\", \"KEY_SEQ\""); | 2852 query.append(" ORDER BY \"FKTABLE_SCHEM\", \"FKTABLE_NAME\", \"FK_NAME\", \"KEY_SEQ\""); |
2886 | 2853 |
2972 // non-empty catalog selection. | 2939 // non-empty catalog selection. |
2973 // as we do not support catalogs this always results in no rows returned | 2940 // as we do not support catalogs this always results in no rows returned |
2974 query.append(" AND 1 = 0"); | 2941 query.append(" AND 1 = 0"); |
2975 } else { | 2942 } else { |
2976 if (pschema != null) { | 2943 if (pschema != null) { |
2977 query.append(" AND \"pkschema\".\"name\" ").append(composeMatchPart(pschema)); | 2944 query.append(" AND pkschema.\"name\" ").append(composeMatchPart(pschema)); |
2978 } | 2945 } |
2979 if (ptable != null) { | 2946 if (ptable != null) { |
2980 query.append(" AND \"pktable\".\"name\" ").append(composeMatchPart(ptable)); | 2947 query.append(" AND pktable.\"name\" ").append(composeMatchPart(ptable)); |
2981 } | 2948 } |
2982 | 2949 |
2983 if (fschema != null) { | 2950 if (fschema != null) { |
2984 query.append(" AND \"fkschema\".\"name\" ").append(composeMatchPart(fschema)); | 2951 query.append(" AND fkschema.\"name\" ").append(composeMatchPart(fschema)); |
2985 } | 2952 } |
2986 if (ftable != null) { | 2953 if (ftable != null) { |
2987 query.append(" AND \"fktable\".\"name\" ").append(composeMatchPart(ftable)); | 2954 query.append(" AND fktable.\"name\" ").append(composeMatchPart(ftable)); |
2988 } | 2955 } |
2989 } | 2956 } |
2990 | 2957 |
2991 query.append(" ORDER BY \"FKTABLE_SCHEM\", \"FKTABLE_NAME\", \"FK_NAME\", \"KEY_SEQ\""); | 2958 query.append(" ORDER BY \"FKTABLE_SCHEM\", \"FKTABLE_NAME\", \"FK_NAME\", \"KEY_SEQ\""); |
2992 | 2959 |
3140 final boolean approximate | 3107 final boolean approximate |
3141 ) throws SQLException | 3108 ) throws SQLException |
3142 { | 3109 { |
3143 String table_row_count = "0"; | 3110 String table_row_count = "0"; |
3144 | 3111 |
3145 if (!approximate && schema != null && table != null && !schema.isEmpty() && !table.isEmpty()) { | 3112 if (!approximate |
3113 && schema != null && !schema.isEmpty() && !schema.contains("%") | |
3114 && table != null && !table.isEmpty() && !table.contains("%")) { | |
3146 // we need the exact cardinality for one specific fully qualified table | 3115 // we need the exact cardinality for one specific fully qualified table |
3147 ResultSet count = null; | 3116 ResultSet count = null; |
3148 try { | 3117 try { |
3149 count = executeMetaDataQuery("SELECT COUNT(*) FROM \"" + schema + "\".\"" + table + "\""); | 3118 count = executeMetaDataQuery("SELECT COUNT(*) FROM \"" + schema + "\".\"" + table + "\""); |
3150 if (count != null && count.next()) { | 3119 if (count != null && count.next()) { |
3160 } | 3129 } |
3161 | 3130 |
3162 final StringBuilder query = new StringBuilder(1250); | 3131 final StringBuilder query = new StringBuilder(1250); |
3163 query.append( | 3132 query.append( |
3164 "SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + | 3133 "SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + |
3165 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 3134 "s.\"name\" AS \"TABLE_SCHEM\", " + |
3166 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 3135 "t.\"name\" AS \"TABLE_NAME\", " + |
3167 "CASE WHEN \"keys\".\"name\" IS NULL THEN true ELSE false END AS \"NON_UNIQUE\", " + | 3136 "CASE WHEN k.\"name\" IS NULL THEN true ELSE false END AS \"NON_UNIQUE\", " + |
3168 "cast(null AS char(1)) AS \"INDEX_QUALIFIER\", " + | 3137 "cast(null AS char(1)) AS \"INDEX_QUALIFIER\", " + |
3169 "\"idxs\".\"name\" AS \"INDEX_NAME\", " + | 3138 "i.\"name\" AS \"INDEX_NAME\", " + |
3170 "CASE \"idxs\".\"type\" WHEN 0 THEN ").append(DatabaseMetaData.tableIndexHashed).append(" ELSE ").append(DatabaseMetaData.tableIndexOther).append(" END AS \"TYPE\", " + | 3139 "CASE i.\"type\" WHEN 0 THEN ").append(DatabaseMetaData.tableIndexHashed).append(" ELSE ").append(DatabaseMetaData.tableIndexOther).append(" END AS \"TYPE\", " + |
3171 "cast(\"objects\".\"nr\" +1 AS smallint) AS \"ORDINAL_POSITION\", "+ | 3140 "cast(o.\"nr\" +1 AS smallint) AS \"ORDINAL_POSITION\", "+ |
3172 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + | 3141 "c.\"name\" AS \"COLUMN_NAME\", " + |
3173 "cast(null AS char(1)) AS \"ASC_OR_DESC\", " + // sort sequence currently not supported in keys or indexes in MonetDB | 3142 "cast(null AS char(1)) AS \"ASC_OR_DESC\", " + // sort sequence currently not supported in keys or indexes in MonetDB |
3174 "cast(").append(table_row_count).append(" AS int) AS \"CARDINALITY\", " + | 3143 "cast(").append(table_row_count).append(" AS int) AS \"CARDINALITY\", " + |
3175 "cast(0 AS int) AS \"PAGES\", " + | 3144 "cast(0 AS int) AS \"PAGES\", " + |
3176 "cast(null AS char(1)) AS \"FILTER_CONDITION\" " + | 3145 "cast(null AS char(1)) AS \"FILTER_CONDITION\" " + |
3177 "FROM \"sys\".\"idxs\" LEFT JOIN \"sys\".\"keys\" ON \"idxs\".\"name\" = \"keys\".\"name\", " + | 3146 "FROM \"sys\".\"idxs\" i " + |
3178 "\"sys\".\"schemas\", " + | 3147 "JOIN \"sys\".\"tables\" t ON i.\"table_id\" = t.\"id\" " + |
3179 "\"sys\".\"objects\", " + | 3148 "JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" " + |
3180 "\"sys\".\"columns\", " + | 3149 "JOIN \"sys\".\"objects\" o ON i.\"id\" = o.\"id\" " + |
3181 "\"sys\".\"tables\" " + | 3150 "JOIN \"sys\".\"columns\" c ON (t.\"id\" = c.\"table_id\" AND o.\"name\" = c.\"name\") " + |
3182 "WHERE \"idxs\".\"table_id\" = \"tables\".\"id\" " + | 3151 "LEFT OUTER JOIN \"sys\".\"keys\" k ON (i.\"name\" = k.\"name\" AND i.\"table_id\" = k.\"table_id\" AND k.\"type\" IN (0,1)) " + // primary (0) and unique keys (1) only |
3183 "AND \"tables\".\"schema_id\" = \"schemas\".\"id\" " + | 3152 "WHERE 1 = 1"); |
3184 "AND \"idxs\".\"id\" = \"objects\".\"id\" " + | |
3185 "AND \"tables\".\"id\" = \"columns\".\"table_id\" " + | |
3186 "AND \"objects\".\"name\" = \"columns\".\"name\" " + | |
3187 "AND (\"keys\".\"type\" IS NULL OR \"keys\".\"type\" = 1)"); | |
3188 | 3153 |
3189 if (catalog != null && !catalog.isEmpty()) { | 3154 if (catalog != null && !catalog.isEmpty()) { |
3190 // non-empty catalog selection. | 3155 // non-empty catalog selection. |
3191 // as we do not support catalogs this always results in no rows returned | 3156 // as we do not support catalogs this always results in no rows returned |
3192 query.append(" AND 1 = 0"); | 3157 query.append(" AND 1 = 0"); |
3193 } else { | 3158 } else { |
3194 if (schema != null) { | 3159 if (schema != null) { |
3195 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schema)); | 3160 query.append(" AND s.\"name\" ").append(composeMatchPart(schema)); |
3196 } | 3161 } |
3197 if (table != null) { | 3162 if (table != null) { |
3198 query.append(" AND \"tables\".\"name\" ").append(composeMatchPart(table)); | 3163 query.append(" AND t.\"name\" ").append(composeMatchPart(table)); |
3199 } | 3164 } |
3200 if (unique) { | 3165 if (unique) { |
3201 query.append(" AND \"keys\".\"name\" IS NOT NULL"); | 3166 query.append(" AND k.\"name\" IS NOT NULL"); |
3202 } | 3167 } |
3203 } | 3168 } |
3204 | 3169 |
3205 query.append(" ORDER BY \"NON_UNIQUE\", \"TYPE\", \"INDEX_NAME\", \"ORDINAL_POSITION\""); | 3170 query.append(" ORDER BY \"NON_UNIQUE\", \"TYPE\", \"INDEX_NAME\", \"ORDINAL_POSITION\""); |
3206 | 3171 |
3335 final StringBuilder query = new StringBuilder(990); | 3300 final StringBuilder query = new StringBuilder(990); |
3336 if (types != null && types.length > 0) { | 3301 if (types != null && types.length > 0) { |
3337 query.append("SELECT * FROM ("); | 3302 query.append("SELECT * FROM ("); |
3338 } | 3303 } |
3339 query.append("SELECT cast(null as char(1)) AS \"TYPE_CAT\", " + | 3304 query.append("SELECT cast(null as char(1)) AS \"TYPE_CAT\", " + |
3340 "\"schemas\".\"name\" AS \"TYPE_SCHEM\", " + | 3305 "s.\"name\" AS \"TYPE_SCHEM\", " + |
3341 "\"types\".\"sqlname\" AS \"TYPE_NAME\", " + | 3306 "t.\"sqlname\" AS \"TYPE_NAME\", " + |
3342 "CASE \"types\".\"sqlname\"" + | 3307 "CASE t.\"sqlname\"" + |
3343 // next 4 UDTs are standard | 3308 // next 4 UDTs are standard |
3344 " WHEN 'inet' THEN 'nl.cwi.monetdb.jdbc.types.INET'" + | 3309 " WHEN 'inet' THEN 'nl.cwi.monetdb.jdbc.types.INET'" + |
3345 " WHEN 'json' THEN 'java.lang.String'" + | 3310 " WHEN 'json' THEN 'java.lang.String'" + |
3346 " WHEN 'url' THEN 'nl.cwi.monetdb.jdbc.types.URL'" + | 3311 " WHEN 'url' THEN 'nl.cwi.monetdb.jdbc.types.URL'" + |
3347 " WHEN 'uuid' THEN 'java.lang.String'" + | 3312 " WHEN 'uuid' THEN 'java.lang.String'" + |
3348 " ELSE 'java.lang.Object' END AS \"CLASS_NAME\", " + | 3313 " ELSE 'java.lang.Object' END AS \"CLASS_NAME\", " + |
3349 "cast(CASE WHEN \"types\".\"sqlname\" IN ('inet', 'json', 'url', 'uuid') THEN ").append(Types.JAVA_OBJECT) | 3314 "cast(CASE WHEN t.\"sqlname\" IN ('inet', 'json', 'url', 'uuid') THEN ").append(Types.JAVA_OBJECT) |
3350 .append(" ELSE ").append(Types.STRUCT).append(" END AS int) AS \"DATA_TYPE\", " + | 3315 .append(" ELSE ").append(Types.STRUCT).append(" END AS int) AS \"DATA_TYPE\", " + |
3351 "\"types\".\"systemname\" AS \"REMARKS\", " + | 3316 "t.\"systemname\" AS \"REMARKS\", " + |
3352 "cast(null as smallint) AS \"BASE_TYPE\" " + | 3317 "cast(null as smallint) AS \"BASE_TYPE\" " + |
3353 "FROM \"sys\".\"types\" JOIN \"sys\".\"schemas\" ON \"types\".\"schema_id\" = \"schemas\".\"id\" " + | 3318 "FROM \"sys\".\"types\" t " + |
3319 "JOIN \"sys\".\"schemas\" s ON t.\"schema_id\" = s.\"id\" " + | |
3354 // exclude the built-in types (I assume they always have id <= 99 and eclass < 15) | 3320 // exclude the built-in types (I assume they always have id <= 99 and eclass < 15) |
3355 "WHERE \"types\".\"id\" > 99 AND \"types\".\"eclass\" >= 15"); | 3321 "WHERE t.\"id\" > 99 AND t.\"eclass\" >= 15"); |
3356 | 3322 |
3357 if (catalog != null && !catalog.isEmpty()) { | 3323 if (catalog != null && !catalog.isEmpty()) { |
3358 // non-empty catalog selection. | 3324 // non-empty catalog selection. |
3359 // as we do not support catalogs this always results in no rows returned | 3325 // as we do not support catalogs this always results in no rows returned |
3360 query.append(" AND 1 = 0"); | 3326 query.append(" AND 1 = 0"); |
3361 } else { | 3327 } else { |
3362 if (schemaPattern != null) { | 3328 if (schemaPattern != null) { |
3363 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 3329 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
3364 } | 3330 } |
3365 if (typeNamePattern != null) { | 3331 if (typeNamePattern != null) { |
3366 query.append(" AND \"types\".\"sqlname\" ").append(composeMatchPart(typeNamePattern)); | 3332 query.append(" AND t.\"sqlname\" ").append(composeMatchPart(typeNamePattern)); |
3367 } | 3333 } |
3368 } | 3334 } |
3369 | 3335 |
3370 if (types != null && types.length > 0) { | 3336 if (types != null && types.length > 0) { |
3371 query.append(") AS getUDTs WHERE \"DATA_TYPE\" IN ("); | 3337 query.append(") AS getUDTs WHERE \"DATA_TYPE\" IN ("); |
3853 * property. This will typically contain information as | 3819 * property. This will typically contain information as |
3854 * to where this property is stored in the database. | 3820 * to where this property is stored in the database. |
3855 * | 3821 * |
3856 * The ResultSet is sorted by the NAME column | 3822 * The ResultSet is sorted by the NAME column |
3857 * | 3823 * |
3858 * @return A ResultSet object; each row is a supported client info | 3824 * @return A ResultSet object; each row is a supported client info property |
3859 * property, none in case of MonetDB's current JDBC driver | |
3860 * @throws SQLException if a database access error occurs | 3825 * @throws SQLException if a database access error occurs |
3861 */ | 3826 */ |
3862 @Override | 3827 @Override |
3863 public ResultSet getClientInfoProperties() throws SQLException { | 3828 public ResultSet getClientInfoProperties() throws SQLException { |
3864 // for a list of connection properties see also MonetConnection.java constructor MonetConnection(Properties props) | 3829 // for a list of connection properties see also MonetConnection.java constructor MonetConnection(Properties props) |
3930 ) throws SQLException | 3895 ) throws SQLException |
3931 { | 3896 { |
3932 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); | 3897 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); |
3933 final StringBuilder query = new StringBuilder(800); | 3898 final StringBuilder query = new StringBuilder(800); |
3934 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + | 3899 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + |
3935 "\"schemas\".\"name\" AS \"FUNCTION_SCHEM\", " + | 3900 "s.\"name\" AS \"FUNCTION_SCHEM\", " + |
3936 "\"functions\".\"name\" AS \"FUNCTION_NAME\", ") | 3901 "f.\"name\" AS \"FUNCTION_NAME\", ") |
3937 .append(useCommentsTable ? "COALESCE(\"comments\".\"remark\", cast(\"functions\".\"func\" as varchar(9999)))" : "cast(\"functions\".\"func\" as varchar(9999))").append(" AS \"REMARKS\", " + | 3902 .append(useCommentsTable ? "COALESCE(cm.\"remark\", cast(f.\"func\" as varchar(9999)))" : "cast(f.\"func\" as varchar(9999))").append(" AS \"REMARKS\", " + |
3938 "CASE \"functions\".\"type\"" + | 3903 "CASE f.\"type\"" + |
3939 " WHEN 1 THEN ").append(DatabaseMetaData.functionNoTable) | 3904 " WHEN 1 THEN ").append(DatabaseMetaData.functionNoTable) |
3940 .append(" WHEN 2 THEN ").append(DatabaseMetaData.functionNoTable) | 3905 .append(" WHEN 2 THEN ").append(DatabaseMetaData.functionNoTable) |
3941 .append(" WHEN 3 THEN ").append(DatabaseMetaData.functionNoTable) | 3906 .append(" WHEN 3 THEN ").append(DatabaseMetaData.functionNoTable) |
3942 .append(" WHEN 4 THEN ").append(DatabaseMetaData.functionNoTable) | 3907 .append(" WHEN 4 THEN ").append(DatabaseMetaData.functionNoTable) |
3943 .append(" WHEN 5 THEN ").append(DatabaseMetaData.functionReturnsTable) | 3908 .append(" WHEN 5 THEN ").append(DatabaseMetaData.functionReturnsTable) |
3944 .append(" WHEN 6 THEN ").append(DatabaseMetaData.functionNoTable) | 3909 .append(" WHEN 6 THEN ").append(DatabaseMetaData.functionNoTable) |
3945 .append(" WHEN 7 THEN ").append(DatabaseMetaData.functionReturnsTable) | 3910 .append(" WHEN 7 THEN ").append(DatabaseMetaData.functionReturnsTable) |
3946 .append(" ELSE ").append(DatabaseMetaData.functionResultUnknown).append(" END AS \"FUNCTION_TYPE\", " + | 3911 .append(" ELSE ").append(DatabaseMetaData.functionResultUnknown).append(" END AS \"FUNCTION_TYPE\", " + |
3947 // only the id value uniquely identifies a function. Include it to be able to differentiate between multiple overloaded functions with the same name | 3912 // only the id value uniquely identifies a function. Include it to be able to differentiate between multiple overloaded functions with the same name |
3948 "cast(\"functions\".\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + | 3913 "cast(f.\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + |
3949 "FROM \"sys\".\"functions\" JOIN \"sys\".\"schemas\" ON (\"functions\".\"schema_id\" = \"schemas\".\"id\") "); | 3914 "FROM \"sys\".\"functions\" f " + |
3915 "JOIN \"sys\".\"schemas\" s ON f.\"schema_id\" = s.\"id\" "); | |
3950 if (useCommentsTable) { | 3916 if (useCommentsTable) { |
3951 query.append("LEFT OUTER JOIN \"sys\".\"comments\" ON (\"functions\".\"id\" = \"comments\".\"id\") "); | 3917 query.append("LEFT OUTER JOIN \"sys\".\"comments\" cm ON (f.\"id\" = cm.\"id\") "); |
3952 } | 3918 } |
3953 // only functions, so exclude procedures (type = 2). Those will to be returned via getProcedures() | 3919 // only functions, so exclude procedures (type = 2). Those will to be returned via getProcedures() |
3954 query.append("WHERE \"functions\".\"type\" <> 2"); | 3920 query.append("WHERE f.\"type\" <> 2"); |
3955 | 3921 |
3956 if (catalog != null && !catalog.isEmpty()) { | 3922 if (catalog != null && !catalog.isEmpty()) { |
3957 // non-empty catalog selection. | 3923 // non-empty catalog selection. |
3958 // as we do not support catalogs this always results in no rows returned | 3924 // as we do not support catalogs this always results in no rows returned |
3959 query.append(" AND 1 = 0"); | 3925 query.append(" AND 1 = 0"); |
3960 } else { | 3926 } else { |
3961 if (schemaPattern != null) { | 3927 if (schemaPattern != null) { |
3962 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 3928 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
3963 } | 3929 } |
3964 if (functionNamePattern != null) { | 3930 if (functionNamePattern != null) { |
3965 query.append(" AND \"functions\".\"name\" ").append(composeMatchPart(functionNamePattern)); | 3931 query.append(" AND f.\"name\" ").append(composeMatchPart(functionNamePattern)); |
3966 } | 3932 } |
3967 } | 3933 } |
3968 | 3934 |
3969 query.append(" ORDER BY \"FUNCTION_SCHEM\", \"FUNCTION_NAME\", \"SPECIFIC_NAME\""); | 3935 query.append(" ORDER BY \"FUNCTION_SCHEM\", \"FUNCTION_NAME\", \"SPECIFIC_NAME\""); |
3970 | 3936 |
4038 final String columnNamePattern | 4004 final String columnNamePattern |
4039 ) throws SQLException | 4005 ) throws SQLException |
4040 { | 4006 { |
4041 final StringBuilder query = new StringBuilder(2600); | 4007 final StringBuilder query = new StringBuilder(2600); |
4042 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + | 4008 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + |
4043 "\"schemas\".\"name\" AS \"FUNCTION_SCHEM\", " + | 4009 "s.\"name\" AS \"FUNCTION_SCHEM\", " + |
4044 "\"functions\".\"name\" AS \"FUNCTION_NAME\", " + | 4010 "f.\"name\" AS \"FUNCTION_NAME\", " + |
4045 "\"args\".\"name\" AS \"COLUMN_NAME\", " + | 4011 "a.\"name\" AS \"COLUMN_NAME\", " + |
4046 "cast(CASE \"args\".\"inout\"" + | 4012 "cast(CASE a.\"inout\"" + |
4047 " WHEN 0 THEN (CASE \"args\".\"number\" WHEN 0 THEN ") | 4013 " WHEN 0 THEN (CASE a.\"number\" WHEN 0 THEN ") |
4048 .append(DatabaseMetaData.functionReturn).append(" ELSE ").append(DatabaseMetaData.functionColumnOut).append(" END)" + | 4014 .append(DatabaseMetaData.functionReturn).append(" ELSE ").append(DatabaseMetaData.functionColumnOut).append(" END)" + |
4049 " WHEN 1 THEN ").append(DatabaseMetaData.functionColumnIn) | 4015 " WHEN 1 THEN ").append(DatabaseMetaData.functionColumnIn) |
4050 .append(" ELSE ").append(DatabaseMetaData.functionColumnUnknown).append(" END AS smallint) AS \"COLUMN_TYPE\", " + | 4016 .append(" ELSE ").append(DatabaseMetaData.functionColumnUnknown).append(" END AS smallint) AS \"COLUMN_TYPE\", " + |
4051 "cast(").append(MonetDriver.getSQLTypeMap("\"args\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + | 4017 "cast(").append(MonetDriver.getSQLTypeMap("a.\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + |
4052 "\"args\".\"type\" AS \"TYPE_NAME\", " + | 4018 "a.\"type\" AS \"TYPE_NAME\", " + |
4053 "CASE \"args\".\"type\" WHEN 'tinyint' THEN 3 WHEN 'smallint' THEN 5 WHEN 'int' THEN 10 WHEN 'bigint' THEN 19" + | 4019 "CASE a.\"type\" WHEN 'tinyint' THEN 3 WHEN 'smallint' THEN 5 WHEN 'int' THEN 10 WHEN 'bigint' THEN 19" + |
4054 " WHEN 'hugeint' THEN 38 WHEN 'oid' THEN 19 WHEN 'wrd' THEN 19 ELSE \"args\".\"type_digits\" END AS \"PRECISION\", " + | 4020 " WHEN 'hugeint' THEN 38 WHEN 'oid' THEN 19 WHEN 'wrd' THEN 19 ELSE a.\"type_digits\" END AS \"PRECISION\", " + |
4055 "CASE \"args\".\"type\" WHEN 'tinyint' THEN 1 WHEN 'smallint' THEN 2 WHEN 'int' THEN 4 WHEN 'bigint' THEN 8" + | 4021 "CASE a.\"type\" WHEN 'tinyint' THEN 1 WHEN 'smallint' THEN 2 WHEN 'int' THEN 4 WHEN 'bigint' THEN 8" + |
4056 " WHEN 'hugeint' THEN 16 WHEN 'oid' THEN 8 WHEN 'wrd' THEN 8 ELSE \"args\".\"type_digits\" END AS \"LENGTH\", " + | 4022 " WHEN 'hugeint' THEN 16 WHEN 'oid' THEN 8 WHEN 'wrd' THEN 8 ELSE a.\"type_digits\" END AS \"LENGTH\", " + |
4057 "cast(CASE WHEN \"args\".\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric'," + | 4023 "cast(CASE WHEN a.\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric'," + |
4058 "'time','timetz','timestamp','timestamptz','sec_interval') THEN \"args\".\"type_scale\" ELSE NULL END AS smallint) AS \"SCALE\", " + | 4024 "'time','timetz','timestamp','timestamptz','sec_interval') THEN a.\"type_scale\" ELSE NULL END AS smallint) AS \"SCALE\", " + |
4059 "cast(CASE WHEN \"args\".\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric') THEN 10" + | 4025 "cast(CASE WHEN a.\"type\" IN ('tinyint','smallint','int','bigint','hugeint','oid','wrd','decimal','numeric') THEN 10" + |
4060 " WHEN \"args\".\"type\" IN ('real','float','double') THEN 2 ELSE NULL END AS smallint) AS \"RADIX\", " + | 4026 " WHEN a.\"type\" IN ('real','float','double') THEN 2 ELSE NULL END AS smallint) AS \"RADIX\", " + |
4061 "cast(").append(DatabaseMetaData.functionNullableUnknown).append(" AS smallint) AS \"NULLABLE\", " + | 4027 "cast(").append(DatabaseMetaData.functionNullableUnknown).append(" AS smallint) AS \"NULLABLE\", " + |
4062 "cast(null as char(1)) AS \"REMARKS\", " + | 4028 "cast(null as char(1)) AS \"REMARKS\", " + |
4063 "cast(CASE WHEN \"args\".\"type\" IN ('char','varchar','clob') THEN \"args\".\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " + | 4029 "cast(CASE WHEN a.\"type\" IN ('char','varchar','clob') THEN a.\"type_digits\" ELSE NULL END as int) AS \"CHAR_OCTET_LENGTH\", " + |
4064 "cast(\"args\".\"number\" as int) AS \"ORDINAL_POSITION\", " + | 4030 "cast(a.\"number\" as int) AS \"ORDINAL_POSITION\", " + |
4065 "cast('' as varchar(3)) AS \"IS_NULLABLE\", " + | 4031 "cast('' as varchar(3)) AS \"IS_NULLABLE\", " + |
4066 // the specific name contains the function id, in order to be able to match the args to the correct overloaded function name | 4032 // the specific name contains the function id, in order to be able to match the args to the correct overloaded function name |
4067 "cast(\"functions\".\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + | 4033 "cast(f.\"id\" as varchar(10)) AS \"SPECIFIC_NAME\" " + |
4068 "FROM \"sys\".\"args\" " + | 4034 "FROM \"sys\".\"args\" a " + |
4069 "JOIN \"sys\".\"functions\" ON (\"args\".\"func_id\" = \"functions\".\"id\") " + | 4035 "JOIN \"sys\".\"functions\" f ON a.\"func_id\" = f.\"id\" " + |
4070 "JOIN \"sys\".\"schemas\" ON (\"functions\".\"schema_id\" = \"schemas\".\"id\") " + | 4036 "JOIN \"sys\".\"schemas\" s ON f.\"schema_id\" = s.\"id\" " + |
4071 // only functions, so exclude procedures (type = 2). Those will to be returned via getProcedureColumns() | 4037 // only functions, so exclude procedures (type = 2). Those will to be returned via getProcedureColumns() |
4072 "WHERE \"functions\".\"type\" <> 2"); | 4038 "WHERE f.\"type\" <> 2"); |
4073 | 4039 |
4074 if (catalog != null && !catalog.isEmpty()) { | 4040 if (catalog != null && !catalog.isEmpty()) { |
4075 // non-empty catalog selection. | 4041 // non-empty catalog selection. |
4076 // as we do not support catalogs this always results in no rows returned | 4042 // as we do not support catalogs this always results in no rows returned |
4077 query.append(" AND 1 = 0"); | 4043 query.append(" AND 1 = 0"); |
4078 } else { | 4044 } else { |
4079 if (schemaPattern != null) { | 4045 if (schemaPattern != null) { |
4080 query.append(" AND \"schemas\".\"name\" ").append(composeMatchPart(schemaPattern)); | 4046 query.append(" AND s.\"name\" ").append(composeMatchPart(schemaPattern)); |
4081 } | 4047 } |
4082 if (functionNamePattern != null) { | 4048 if (functionNamePattern != null) { |
4083 query.append(" AND \"functions\".\"name\" ").append(composeMatchPart(functionNamePattern)); | 4049 query.append(" AND f.\"name\" ").append(composeMatchPart(functionNamePattern)); |
4084 } | 4050 } |
4085 if (columnNamePattern != null) { | 4051 if (columnNamePattern != null) { |
4086 query.append(" AND \"args\".\"name\" ").append(composeMatchPart(columnNamePattern)); | 4052 query.append(" AND a.\"name\" ").append(composeMatchPart(columnNamePattern)); |
4087 } | 4053 } |
4088 } | 4054 } |
4089 | 4055 |
4090 query.append(" ORDER BY \"FUNCTION_SCHEM\", \"FUNCTION_NAME\", \"SPECIFIC_NAME\", \"ORDINAL_POSITION\""); | 4056 query.append(" ORDER BY \"FUNCTION_SCHEM\", \"FUNCTION_NAME\", \"SPECIFIC_NAME\", \"ORDINAL_POSITION\""); |
4091 | 4057 |