Mercurial > hg > monetdb-java
comparison src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java @ 295:003ae6d881db
Add "final" keyword to method arguments and local variables where possible.
It discovered some bugs in the MonetStatement constructor (changed the argument instead of object variable) which are fixed now.
See also https://en.wikipedia.org/wiki/Final_(Java)
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 01 Aug 2019 20:18:43 +0200 (2019-08-01) |
parents | 894abb249de1 |
children | 6db8f6702ce8 |
comparison
equal
deleted
inserted
replaced
294:894abb249de1 | 295:003ae6d881db |
---|---|
15 import java.sql.ResultSet; | 15 import java.sql.ResultSet; |
16 import java.sql.ResultSetMetaData; | 16 import java.sql.ResultSetMetaData; |
17 import java.sql.RowIdLifetime; | 17 import java.sql.RowIdLifetime; |
18 import java.sql.Types; | 18 import java.sql.Types; |
19 | 19 |
20 import java.util.ArrayList; | |
21 | |
22 /** | 20 /** |
23 * A DatabaseMetaData object suitable for the MonetDB database. | 21 * A DatabaseMetaData object suitable for the MonetDB database. |
24 * | 22 * |
25 * @author Fabian Groffen, Martin van Dinther | 23 * @author Fabian Groffen, Martin van Dinther |
26 * @version 0.7 | 24 * @version 0.7 |
27 */ | 25 */ |
28 public class MonetDatabaseMetaData extends MonetWrapper implements DatabaseMetaData { | 26 public class MonetDatabaseMetaData |
27 extends MonetWrapper | |
28 implements DatabaseMetaData | |
29 { | |
29 private final Connection con; | 30 private final Connection con; |
30 | 31 |
31 // Internal cache for 3 server environment values | 32 // Internal cache for 3 server environment values |
32 private String env_current_user; | 33 private String env_current_user; |
33 private String env_monet_version; | 34 private String env_monet_version; |
34 private String env_max_clients; | 35 private String env_max_clients; |
35 | 36 |
36 public MonetDatabaseMetaData(Connection parent) { | 37 public MonetDatabaseMetaData(final Connection parent) { |
37 con = parent; | 38 con = parent; |
38 } | 39 } |
39 | 40 |
40 /** | 41 /** |
41 * Utility method to fetch some server environment values combined in one query for efficiency. | 42 * Utility method to fetch some server environment values combined in one query for efficiency. |
82 // for debug: System.out.println("Read: env_current_user: " + env_current_user + " env_monet_version: " + env_monet_version + " env_max_clients: " + env_max_clients); | 83 // for debug: System.out.println("Read: env_current_user: " + env_current_user + " env_monet_version: " + env_monet_version + " env_max_clients: " + env_max_clients); |
83 } | 84 } |
84 | 85 |
85 | 86 |
86 /** | 87 /** |
87 * Internal utility method to create a Statement object, execute a query and return the ResulSet object. | 88 * Internal utility method to create a Statement object, execute a query and return the ResulSet object which allows scrolling. |
88 * As the Statement object is created internally (the caller does not see it and thus can not close it), | 89 * As the Statement object is created internally (the caller does not see it and thus can not close it), |
89 * we set it to close (and free server resources) when the ResultSet object is closed by the caller. | 90 * we set it to close (and free server resources) when the ResultSet object is closed by the caller. |
90 */ | 91 */ |
91 private ResultSet executeMetaDataQuery(String query) throws SQLException { | 92 private ResultSet executeMetaDataQuery(final String query) throws SQLException { |
92 Statement stmt = null; | 93 final Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); |
93 ResultSet rs = null; | 94 ResultSet rs = null; |
94 stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); | |
95 if (stmt != null) { | 95 if (stmt != null) { |
96 // for debug: System.out.println("SQL (len " + query.length() + "): " + query); | 96 // for debug: System.out.println("SQL (len " + query.length() + "): " + query); |
97 rs = stmt.executeQuery(query); | 97 rs = stmt.executeQuery(query); |
98 if (rs != null) { | 98 if (rs != null) { |
99 /* we want the statement object to be closed also when the resultset is closed by the caller */ | 99 /* we want the statement object to be closed also when the resultset is closed by the caller */ |
408 * | 408 * |
409 * @return a comma separated list of MonetDB keywords | 409 * @return a comma separated list of MonetDB keywords |
410 */ | 410 */ |
411 @Override | 411 @Override |
412 public String getSQLKeywords() { | 412 public String getSQLKeywords() { |
413 String keywords = getConcatenatedStringFromQuery("SELECT \"keyword\" FROM \"sys\".\"keywords\" ORDER BY 1"); | 413 final String keywords = getConcatenatedStringFromQuery("SELECT \"keyword\" FROM \"sys\".\"keywords\" ORDER BY 1"); |
414 | 414 |
415 /* An old MonetDB server (pre Jul2015 release) will not have a table sys.keywords and return an empty String */ | 415 /* An old MonetDB server (pre Jul2015 release) will not have a table sys.keywords and return an empty String */ |
416 return (keywords.isEmpty()) ? | 416 return (keywords.isEmpty()) ? |
417 /* for old servers return static list (as returned in clients/odbc/driver/SQLGetInfo.c case SQL_KEYWORDS:) */ | 417 /* for old servers return static list (as returned in clients/odbc/driver/SQLGetInfo.c case SQL_KEYWORDS:) */ |
418 "ADMIN,AFTER,AGGREGATE,ALWAYS,ASYMMETRIC,ATOMIC," + | 418 "ADMIN,AFTER,AGGREGATE,ALWAYS,ASYMMETRIC,ATOMIC," + |
440 /** | 440 /** |
441 * Internal utility method getConcatenatedStringFromQuery(String query) | 441 * Internal utility method getConcatenatedStringFromQuery(String query) |
442 * args: query: SQL SELECT query. Only the output of the first column is concatenated. | 442 * args: query: SQL SELECT query. Only the output of the first column is concatenated. |
443 * @return a String of query result values concatenated into one string, and values separated by comma's | 443 * @return a String of query result values concatenated into one string, and values separated by comma's |
444 */ | 444 */ |
445 private String getConcatenatedStringFromQuery(String query) { | 445 private String getConcatenatedStringFromQuery(final String query) { |
446 StringBuilder sb = new StringBuilder(1024); | 446 final StringBuilder sb = new StringBuilder(1024); |
447 Statement st = null; | 447 Statement st = null; |
448 ResultSet rs = null; | 448 ResultSet rs = null; |
449 try { | 449 try { |
450 st = con.createStatement(); | 450 st = con.createStatement(); |
451 rs = st.executeQuery(query); | 451 rs = st.executeQuery(query); |
487 private static final String OrFunctionsMaxMin = " OR \"name\" IN ('sql_max','sql_min','least','greatest')"; | 487 private static final String OrFunctionsMaxMin = " OR \"name\" IN ('sql_max','sql_min','least','greatest')"; |
488 private static final String FunctionsOrderBy1 = " ORDER BY 1"; | 488 private static final String FunctionsOrderBy1 = " ORDER BY 1"; |
489 | 489 |
490 @Override | 490 @Override |
491 public String getNumericFunctions() { | 491 public String getNumericFunctions() { |
492 String match = | 492 final String match = |
493 "('tinyint', 'smallint', 'int', 'bigint', 'hugeint', 'decimal', 'double', 'real') )" + | 493 "('tinyint', 'smallint', 'int', 'bigint', 'hugeint', 'decimal', 'double', 'real') )" + |
494 " AND \"type\" = 1" + // only scalar functions | 494 " AND \"type\" = 1" + // only scalar functions |
495 // exclude functions which belong to the 'str' module | 495 // exclude functions which belong to the 'str' module |
496 " AND \"mod\" <> 'str')" + // to filter out string functions: 'code' and 'space' | 496 " AND \"mod\" <> 'str')" + // to filter out string functions: 'code' and 'space' |
497 " OR \"name\" IN ('degrees','fuse','pi','ms_round','ms_str','ms_trunc','radians')"; | 497 " OR \"name\" IN ('degrees','fuse','pi','ms_round','ms_str','ms_trunc','radians')"; |
498 return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + OrFunctionsMaxMin + FunctionsOrderBy1); | 498 return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + OrFunctionsMaxMin + FunctionsOrderBy1); |
499 } | 499 } |
500 | 500 |
501 @Override | 501 @Override |
502 public String getStringFunctions() { | 502 public String getStringFunctions() { |
503 String match = | 503 final String match = |
504 "('char', 'varchar', 'clob', 'json') )" + | 504 "('char', 'varchar', 'clob', 'json') )" + |
505 // include functions which belong to the 'str' module | 505 // include functions which belong to the 'str' module |
506 " OR \"mod\" = 'str')"; | 506 " OR \"mod\" = 'str')"; |
507 String unionPart = | 507 final String unionPart = |
508 // add system functions which are not listed in sys.functions but implemented in the SQL parser (see sql/server/sql_parser.y) | 508 // add system functions which are not listed in sys.functions but implemented in the SQL parser (see sql/server/sql_parser.y) |
509 " UNION SELECT 'position'"; | 509 " UNION SELECT 'position'"; |
510 return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + OrFunctionsMaxMin + unionPart + FunctionsOrderBy1); | 510 return getConcatenatedStringFromQuery(FunctionsSelect + FunctionsWhere + match + OrFunctionsMaxMin + unionPart + FunctionsOrderBy1); |
511 } | 511 } |
512 | 512 |
513 @Override | 513 @Override |
514 public String getSystemFunctions() { | 514 public String getSystemFunctions() { |
515 // Note: As of Apr2019 (11.33.3) release the system table systemfunctions is replaced by a view which queries functions.system | 515 // Note: As of Apr2019 (11.33.3) release the system table systemfunctions is replaced by a view which queries functions.system |
516 // TODO: Replace join to sys.systemfunctions with " AND \"system\" " but only if the server-version is >= 11.33.3 | 516 // TODO: Replace join to sys.systemfunctions with " AND \"system\" " but only if the server-version is >= 11.33.3 |
517 String wherePart = | 517 final String wherePart = |
518 "\"id\" NOT IN (SELECT \"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1)" + // without any args | 518 "\"id\" NOT IN (SELECT \"func_id\" FROM \"sys\".\"args\" WHERE \"number\" = 1)" + // without any args |
519 " AND \"id\" IN (SELECT \"function_id\" FROM \"sys\".\"systemfunctions\")" + // only functions marked as system | 519 " AND \"id\" IN (SELECT \"function_id\" FROM \"sys\".\"systemfunctions\")" + // only functions marked as system |
520 " AND \"type\" = 1" + // only scalar functions | 520 " AND \"type\" = 1" + // only scalar functions |
521 // exclude functions which belong to the 'mtime' module | 521 // exclude functions which belong to the 'mtime' module |
522 " AND \"mod\" <> 'mtime'" + | 522 " AND \"mod\" <> 'mtime'" + |
531 return getConcatenatedStringFromQuery(FunctionsSelect + wherePart + FunctionsOrderBy1); | 531 return getConcatenatedStringFromQuery(FunctionsSelect + wherePart + FunctionsOrderBy1); |
532 } | 532 } |
533 | 533 |
534 @Override | 534 @Override |
535 public String getTimeDateFunctions() { | 535 public String getTimeDateFunctions() { |
536 String wherePart = | 536 final String wherePart = |
537 "\"mod\" IN ('mtime','timestamp') OR \"name\" IN ('localtime','localtimestamp','date_trunc')"; | 537 "\"mod\" IN ('mtime','timestamp') OR \"name\" IN ('localtime','localtimestamp','date_trunc')"; |
538 String unionPart = | 538 final String unionPart = |
539 // add time date functions which are not listed in sys.functions but implemented in the SQL parser (see sql/server/sql_parser.y) | 539 // add time date functions which are not listed in sys.functions but implemented in the SQL parser (see sql/server/sql_parser.y) |
540 " UNION SELECT 'extract'" + | 540 " UNION SELECT 'extract'" + |
541 " UNION SELECT 'now'"; | 541 " UNION SELECT 'now'"; |
542 return getConcatenatedStringFromQuery(FunctionsSelect + wherePart + OrFunctionsMaxMin + unionPart + FunctionsOrderBy1); | 542 return getConcatenatedStringFromQuery(FunctionsSelect + wherePart + OrFunctionsMaxMin + unionPart + FunctionsOrderBy1); |
543 } | 543 } |
636 * The JDBC types are the generic SQL data types defined in java.sql.Types. | 636 * The JDBC types are the generic SQL data types defined in java.sql.Types. |
637 * | 637 * |
638 * @return true if so; false otherwise | 638 * @return true if so; false otherwise |
639 */ | 639 */ |
640 @Override | 640 @Override |
641 public boolean supportsConvert(int fromType, int toType) { | 641 public boolean supportsConvert(final int fromType, final int toType) { |
642 switch (fromType) { | 642 switch (fromType) { |
643 case Types.BOOLEAN: | 643 case Types.BOOLEAN: |
644 switch (toType) { | 644 switch (toType) { |
645 case Types.BOOLEAN: | 645 case Types.BOOLEAN: |
646 /* case Types.BIT: is not supported by MonetDB and will fail */ | 646 /* case Types.BIT: is not supported by MonetDB and will fail */ |
1625 * @param level the values are defined in java.sql.Connection | 1625 * @param level the values are defined in java.sql.Connection |
1626 * @return true if so | 1626 * @return true if so |
1627 * @see Connection | 1627 * @see Connection |
1628 */ | 1628 */ |
1629 @Override | 1629 @Override |
1630 public boolean supportsTransactionIsolationLevel(int level) { | 1630 public boolean supportsTransactionIsolationLevel(final int level) { |
1631 return level == Connection.TRANSACTION_SERIALIZABLE; | 1631 return level == Connection.TRANSACTION_SERIALIZABLE; |
1632 } | 1632 } |
1633 | 1633 |
1634 /** | 1634 /** |
1635 * Are both data definition and data manipulation transactions | 1635 * Are both data definition and data manipulation transactions |
1724 * @return ResultSet - each row is a procedure description | 1724 * @return ResultSet - each row is a procedure description |
1725 * @throws SQLException if a database access error occurs | 1725 * @throws SQLException if a database access error occurs |
1726 */ | 1726 */ |
1727 @Override | 1727 @Override |
1728 public ResultSet getProcedures( | 1728 public ResultSet getProcedures( |
1729 String catalog, | 1729 final String catalog, |
1730 String schemaPattern, | 1730 final String schemaPattern, |
1731 String procedureNamePattern | 1731 final String procedureNamePattern |
1732 ) throws SQLException | 1732 ) throws SQLException |
1733 { | 1733 { |
1734 boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); | 1734 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); |
1735 StringBuilder query = new StringBuilder(980); | 1735 final StringBuilder query = new StringBuilder(980); |
1736 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + | 1736 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + |
1737 "\"schemas\".\"name\" AS \"PROCEDURE_SCHEM\", " + | 1737 "\"schemas\".\"name\" AS \"PROCEDURE_SCHEM\", " + |
1738 "\"functions\".\"name\" AS \"PROCEDURE_NAME\", " + | 1738 "\"functions\".\"name\" AS \"PROCEDURE_NAME\", " + |
1739 "cast(null as char(1)) AS \"Field4\", " + | 1739 "cast(null as char(1)) AS \"Field4\", " + |
1740 "cast(null as char(1)) AS \"Field5\", " + | 1740 "cast(null as char(1)) AS \"Field5\", " + |
1837 * @throws SQLException if a database-access error occurs | 1837 * @throws SQLException if a database-access error occurs |
1838 * @see #getSearchStringEscape | 1838 * @see #getSearchStringEscape |
1839 */ | 1839 */ |
1840 @Override | 1840 @Override |
1841 public ResultSet getProcedureColumns( | 1841 public ResultSet getProcedureColumns( |
1842 String catalog, | 1842 final String catalog, |
1843 String schemaPattern, | 1843 final String schemaPattern, |
1844 String procedureNamePattern, | 1844 final String procedureNamePattern, |
1845 String columnNamePattern | 1845 final String columnNamePattern |
1846 ) throws SQLException { | 1846 ) throws SQLException { |
1847 StringBuilder query = new StringBuilder(2900); | 1847 final StringBuilder query = new StringBuilder(2900); |
1848 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + | 1848 query.append("SELECT cast(null as char(1)) AS \"PROCEDURE_CAT\", " + |
1849 "\"schemas\".\"name\" AS \"PROCEDURE_SCHEM\", " + | 1849 "\"schemas\".\"name\" AS \"PROCEDURE_SCHEM\", " + |
1850 "\"functions\".\"name\" AS \"PROCEDURE_NAME\", " + | 1850 "\"functions\".\"name\" AS \"PROCEDURE_NAME\", " + |
1851 "\"args\".\"name\" AS \"COLUMN_NAME\", " + | 1851 "\"args\".\"name\" AS \"COLUMN_NAME\", " + |
1852 "cast(CASE \"args\".\"inout\"" + | 1852 "cast(CASE \"args\".\"inout\"" + |
1905 * compose an exact match (use =) or match with wildcards (use LIKE) or IS NULL | 1905 * compose an exact match (use =) or match with wildcards (use LIKE) or IS NULL |
1906 * | 1906 * |
1907 * @param in the string to match | 1907 * @param in the string to match |
1908 * @return the SQL match part string | 1908 * @return the SQL match part string |
1909 */ | 1909 */ |
1910 private static final String composeMatchPart(String in) { | 1910 private static final String composeMatchPart(final String in) { |
1911 if (in == null) | 1911 if (in == null) |
1912 return "IS NULL"; | 1912 return "IS NULL"; |
1913 | 1913 |
1914 String sql = "= '"; | 1914 String sql = "= '"; |
1915 // check if SQL wildcards are used in the input, if so use LIKE | 1915 // check if SQL wildcards are used in the input, if so use LIKE |
1916 if (in.contains("%") || in.contains("_")) | 1916 if (in.contains("%") || in.contains("_")) |
1917 sql = "LIKE '"; | 1917 sql = "LIKE '"; |
1918 | 1918 |
1919 // all slashes and single quotes in input are escaped with a slash. | 1919 // all slashes and single quotes in input are escaped with a slash. |
1920 String escaped = in.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'"); | 1920 final String escaped = in.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'"); |
1921 | 1921 |
1922 return sql + escaped + "'"; | 1922 return sql + escaped + "'"; |
1923 } | 1923 } |
1924 | 1924 |
1925 /** | 1925 /** |
1972 * @return ResultSet - each row is a table description | 1972 * @return ResultSet - each row is a table description |
1973 * @throws SQLException if a database-access error occurs. | 1973 * @throws SQLException if a database-access error occurs. |
1974 */ | 1974 */ |
1975 @Override | 1975 @Override |
1976 public ResultSet getTables( | 1976 public ResultSet getTables( |
1977 String catalog, | 1977 final String catalog, |
1978 String schemaPattern, | 1978 final String schemaPattern, |
1979 String tableNamePattern, | 1979 final String tableNamePattern, |
1980 String types[] | 1980 final String types[] |
1981 ) throws SQLException | 1981 ) throws SQLException |
1982 { | 1982 { |
1983 // as of Jul2015 release the sys.tables.type values (0 through 6) is extended with new values 10, 11, 20, and 30 (for system and temp tables/views). | 1983 // as of Jul2015 release the sys.tables.type values (0 through 6) is extended with new values 10, 11, 20, and 30 (for system and temp tables/views). |
1984 // as of Jul2015 release we also have a new table: sys.table_types with names for the new table types | 1984 // as of Jul2015 release we also have a new table: sys.table_types with names for the new table types |
1985 // for correct behavior we need to know if the server is using the old (pre Jul2015) or new sys.tables.type values | 1985 // for correct behavior we need to know if the server is using the old (pre Jul2015) or new sys.tables.type values |
1986 boolean preJul2015 = ("11.19.15".compareTo(getDatabaseProductVersion()) >= 0); | 1986 final boolean preJul2015 = ("11.19.15".compareTo(getDatabaseProductVersion()) >= 0); |
1987 /* for debug: System.out.println("getDatabaseProductVersion() is " + getDatabaseProductVersion() + " preJul2015 is " + preJul2015); */ | 1987 /* for debug: System.out.println("getDatabaseProductVersion() is " + getDatabaseProductVersion() + " preJul2015 is " + preJul2015); */ |
1988 | 1988 |
1989 boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); | 1989 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); |
1990 StringBuilder query = new StringBuilder(1600); | 1990 final StringBuilder query = new StringBuilder(1600); |
1991 if (preJul2015 && types != null && types.length > 0) { | 1991 if (preJul2015 && types != null && types.length > 0) { |
1992 // we need to filter on the constructed "TABLE_TYPE" expression, this is only possible when we use a subquery in the FROM | 1992 // we need to filter on the constructed "TABLE_TYPE" expression, this is only possible when we use a subquery in the FROM |
1993 query.append("SELECT * FROM ("); | 1993 query.append("SELECT * FROM ("); |
1994 } | 1994 } |
1995 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 1995 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
2081 * @return ResultSet each row has a single String column that is a | 2081 * @return ResultSet each row has a single String column that is a |
2082 * schema name | 2082 * schema name |
2083 * @throws SQLException if a database error occurs | 2083 * @throws SQLException if a database error occurs |
2084 */ | 2084 */ |
2085 @Override | 2085 @Override |
2086 public ResultSet getSchemas(String catalog, String schemaPattern) | 2086 public ResultSet getSchemas(final String catalog, final String schemaPattern) |
2087 throws SQLException | 2087 throws SQLException |
2088 { | 2088 { |
2089 StringBuilder query = new StringBuilder(170); | 2089 final StringBuilder query = new StringBuilder(170); |
2090 query.append("SELECT \"name\" AS \"TABLE_SCHEM\", " + | 2090 query.append("SELECT \"name\" AS \"TABLE_SCHEM\", " + |
2091 "cast(null as char(1)) AS \"TABLE_CATALOG\" " + | 2091 "cast(null as char(1)) AS \"TABLE_CATALOG\" " + |
2092 "FROM \"sys\".\"schemas\""); | 2092 "FROM \"sys\".\"schemas\""); |
2093 | 2093 |
2094 if (catalog != null && !catalog.isEmpty()) { | 2094 if (catalog != null && !catalog.isEmpty()) { |
2142 * @throws SQLException if a database error occurs | 2142 * @throws SQLException if a database error occurs |
2143 */ | 2143 */ |
2144 @Override | 2144 @Override |
2145 public ResultSet getTableTypes() throws SQLException { | 2145 public ResultSet getTableTypes() throws SQLException { |
2146 // as of Jul2015 release we have a new table: sys.table_types with more table types | 2146 // as of Jul2015 release we have a new table: sys.table_types with more table types |
2147 String query = "SELECT \"table_type_name\" AS \"TABLE_TYPE\" FROM \"sys\".\"table_types\" ORDER BY 1"; | |
2148 // For old (pre jul2015) servers fall back to old behavior. | 2147 // For old (pre jul2015) servers fall back to old behavior. |
2149 boolean preJul2015 = ("11.19.15".compareTo(getDatabaseProductVersion()) >= 0); | 2148 final boolean preJul2015 = ("11.19.15".compareTo(getDatabaseProductVersion()) >= 0); |
2150 if (preJul2015) { | 2149 final String query = preJul2015 |
2151 query = "SELECT 'SESSION TABLE' AS \"TABLE_TYPE\" UNION ALL " + | 2150 ? "SELECT 'SESSION TABLE' AS \"TABLE_TYPE\" UNION ALL " + |
2152 "SELECT 'SESSION VIEW' UNION ALL " + | 2151 "SELECT 'SESSION VIEW' UNION ALL " + |
2153 "SELECT 'SYSTEM SESSION TABLE' UNION ALL " + | 2152 "SELECT 'SYSTEM SESSION TABLE' UNION ALL " + |
2154 "SELECT 'SYSTEM SESSION VIEW' UNION ALL " + | 2153 "SELECT 'SYSTEM SESSION VIEW' UNION ALL " + |
2155 "SELECT 'SYSTEM TABLE' UNION ALL " + | 2154 "SELECT 'SYSTEM TABLE' UNION ALL " + |
2156 "SELECT 'SYSTEM VIEW' UNION ALL " + | 2155 "SELECT 'SYSTEM VIEW' UNION ALL " + |
2157 "SELECT 'TABLE' UNION ALL " + | 2156 "SELECT 'TABLE' UNION ALL " + |
2158 "SELECT 'VIEW' ORDER BY 1"; | 2157 "SELECT 'VIEW' ORDER BY 1" |
2159 } | 2158 : "SELECT \"table_type_name\" AS \"TABLE_TYPE\" FROM \"sys\".\"table_types\" ORDER BY 1"; |
2160 | 2159 |
2161 return executeMetaDataQuery(query); | 2160 return executeMetaDataQuery(query); |
2162 } | 2161 } |
2163 | 2162 |
2164 /** | 2163 /** |
2232 * @throws SQLException if a database error occurs | 2231 * @throws SQLException if a database error occurs |
2233 * @see #getSearchStringEscape | 2232 * @see #getSearchStringEscape |
2234 */ | 2233 */ |
2235 @Override | 2234 @Override |
2236 public ResultSet getColumns( | 2235 public ResultSet getColumns( |
2237 String catalog, | 2236 final String catalog, |
2238 String schemaPattern, | 2237 final String schemaPattern, |
2239 String tableNamePattern, | 2238 final String tableNamePattern, |
2240 String columnNamePattern | 2239 final String columnNamePattern |
2241 ) throws SQLException | 2240 ) throws SQLException |
2242 { | 2241 { |
2243 boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); | 2242 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); |
2244 StringBuilder query = new StringBuilder(2450); | 2243 final StringBuilder query = new StringBuilder(2450); |
2245 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 2244 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
2246 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2245 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + |
2247 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2246 "\"tables\".\"name\" AS \"TABLE_NAME\", " + |
2248 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + | 2247 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + |
2249 "cast(").append(MonetDriver.getSQLTypeMap("\"columns\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + | 2248 "cast(").append(MonetDriver.getSQLTypeMap("\"columns\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + |
2330 * @see #getSearchStringEscape | 2329 * @see #getSearchStringEscape |
2331 * @throws SQLException if a database error occurs | 2330 * @throws SQLException if a database error occurs |
2332 */ | 2331 */ |
2333 @Override | 2332 @Override |
2334 public ResultSet getColumnPrivileges( | 2333 public ResultSet getColumnPrivileges( |
2335 String catalog, | 2334 final String catalog, |
2336 String schemaPattern, | 2335 final String schemaPattern, |
2337 String tableNamePattern, | 2336 final String tableNamePattern, |
2338 String columnNamePattern | 2337 final String columnNamePattern |
2339 ) throws SQLException | 2338 ) throws SQLException |
2340 { | 2339 { |
2341 boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); | 2340 final boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); |
2342 StringBuilder query = new StringBuilder(1100); | 2341 final StringBuilder query = new StringBuilder(1100); |
2343 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 2342 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
2344 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2343 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + |
2345 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2344 "\"tables\".\"name\" AS \"TABLE_NAME\", " + |
2346 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + | 2345 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + |
2347 "\"grantors\".\"name\" AS \"GRANTOR\", " + | 2346 "\"grantors\".\"name\" AS \"GRANTOR\", " + |
2429 * @see #getSearchStringEscape | 2428 * @see #getSearchStringEscape |
2430 * @throws SQLException if a database error occurs | 2429 * @throws SQLException if a database error occurs |
2431 */ | 2430 */ |
2432 @Override | 2431 @Override |
2433 public ResultSet getTablePrivileges( | 2432 public ResultSet getTablePrivileges( |
2434 String catalog, | 2433 final String catalog, |
2435 String schemaPattern, | 2434 final String schemaPattern, |
2436 String tableNamePattern | 2435 final String tableNamePattern |
2437 ) throws SQLException | 2436 ) throws SQLException |
2438 { | 2437 { |
2439 boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); | 2438 final boolean usePrivilege_codesTable = ((MonetConnection)con).privilege_codesTableExists(); |
2440 StringBuilder query = new StringBuilder(1000); | 2439 final StringBuilder query = new StringBuilder(1000); |
2441 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 2440 query.append("SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
2442 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2441 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + |
2443 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2442 "\"tables\".\"name\" AS \"TABLE_NAME\", " + |
2444 "\"grantors\".\"name\" AS \"GRANTOR\", " + | 2443 "\"grantors\".\"name\" AS \"GRANTOR\", " + |
2445 "\"grantees\".\"name\" AS \"GRANTEE\", ") | 2444 "\"grantees\".\"name\" AS \"GRANTEE\", ") |
2528 * @return ResultSet each row is a column description | 2527 * @return ResultSet each row is a column description |
2529 * @throws SQLException if a database error occurs | 2528 * @throws SQLException if a database error occurs |
2530 */ | 2529 */ |
2531 @Override | 2530 @Override |
2532 public ResultSet getBestRowIdentifier( | 2531 public ResultSet getBestRowIdentifier( |
2533 String catalog, | 2532 final String catalog, |
2534 String schema, | 2533 final String schema, |
2535 String table, | 2534 final String table, |
2536 int scope, | 2535 final int scope, |
2537 boolean nullable | 2536 final boolean nullable |
2538 ) throws SQLException | 2537 ) throws SQLException |
2539 { | 2538 { |
2540 StringBuilder query = new StringBuilder(1500); | 2539 final StringBuilder query = new StringBuilder(1500); |
2541 query.append("SELECT cast(").append(DatabaseMetaData.bestRowSession).append(" AS smallint) AS \"SCOPE\", " + | 2540 query.append("SELECT cast(").append(DatabaseMetaData.bestRowSession).append(" AS smallint) AS \"SCOPE\", " + |
2542 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + | 2541 "\"columns\".\"name\" AS \"COLUMN_NAME\", " + |
2543 "cast(").append(MonetDriver.getSQLTypeMap("\"columns\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + | 2542 "cast(").append(MonetDriver.getSQLTypeMap("\"columns\".\"type\"")).append(" AS int) AS \"DATA_TYPE\", " + |
2544 "\"columns\".\"type\" AS \"TYPE_NAME\", " + | 2543 "\"columns\".\"type\" AS \"TYPE_NAME\", " + |
2545 "\"columns\".\"type_digits\" AS \"COLUMN_SIZE\", " + | 2544 "\"columns\".\"type_digits\" AS \"COLUMN_SIZE\", " + |
2613 * @return ResultSet each row is a column description | 2612 * @return ResultSet each row is a column description |
2614 * @throws SQLException if a database error occurs | 2613 * @throws SQLException if a database error occurs |
2615 */ | 2614 */ |
2616 @Override | 2615 @Override |
2617 public ResultSet getVersionColumns( | 2616 public ResultSet getVersionColumns( |
2618 String catalog, | 2617 final String catalog, |
2619 String schema, | 2618 final String schema, |
2620 String table | 2619 final String table |
2621 ) throws SQLException | 2620 ) throws SQLException |
2622 { | 2621 { |
2623 // MonetDB currently does not have columns which update themselves, so return an empty ResultSet | 2622 // MonetDB currently does not have columns which update themselves, so return an empty ResultSet |
2624 String query = | 2623 final String query = |
2625 "SELECT cast(0 as smallint) AS \"SCOPE\", " + | 2624 "SELECT cast(0 as smallint) AS \"SCOPE\", " + |
2626 "cast(null as char(1)) AS \"COLUMN_NAME\", " + | 2625 "cast(null as char(1)) AS \"COLUMN_NAME\", " + |
2627 "cast(0 as int) AS \"DATA_TYPE\", " + | 2626 "cast(0 as int) AS \"DATA_TYPE\", " + |
2628 "cast(null as char(1)) AS \"TYPE_NAME\", " + | 2627 "cast(null as char(1)) AS \"TYPE_NAME\", " + |
2629 "cast(0 as int) AS \"COLUMN_SIZE\", " + | 2628 "cast(0 as int) AS \"COLUMN_SIZE\", " + |
2656 * @return ResultSet each row is a primary key column description | 2655 * @return ResultSet each row is a primary key column description |
2657 * @throws SQLException if a database error occurs | 2656 * @throws SQLException if a database error occurs |
2658 */ | 2657 */ |
2659 @Override | 2658 @Override |
2660 public ResultSet getPrimaryKeys( | 2659 public ResultSet getPrimaryKeys( |
2661 String catalog, | 2660 final String catalog, |
2662 String schema, | 2661 final String schema, |
2663 String table | 2662 final String table |
2664 ) throws SQLException | 2663 ) throws SQLException |
2665 { | 2664 { |
2666 StringBuilder query = new StringBuilder(600); | 2665 final StringBuilder query = new StringBuilder(600); |
2667 query.append("SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + | 2666 query.append("SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + |
2668 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 2667 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + |
2669 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 2668 "\"tables\".\"name\" AS \"TABLE_NAME\", " + |
2670 "\"objects\".\"name\" AS \"COLUMN_NAME\", " + | 2669 "\"objects\".\"name\" AS \"COLUMN_NAME\", " + |
2671 "cast(1 + \"objects\".\"nr\" AS smallint) AS \"KEY_SEQ\", " + | 2670 "cast(1 + \"objects\".\"nr\" AS smallint) AS \"KEY_SEQ\", " + |
2791 * @return ResultSet each row is a primary key column description | 2790 * @return ResultSet each row is a primary key column description |
2792 * @see #getExportedKeys | 2791 * @see #getExportedKeys |
2793 * @throws SQLException if a database error occurs | 2792 * @throws SQLException if a database error occurs |
2794 */ | 2793 */ |
2795 @Override | 2794 @Override |
2796 public ResultSet getImportedKeys(String catalog, String schema, String table) | 2795 public ResultSet getImportedKeys( |
2797 throws SQLException | 2796 final String catalog, |
2797 final String schema, | |
2798 final String table | |
2799 ) throws SQLException | |
2798 { | 2800 { |
2799 StringBuilder query = new StringBuilder(keyQuery.length() + 250); | 2801 final StringBuilder query = new StringBuilder(keyQuery.length() + 250); |
2800 query.append(keyQuery); | 2802 query.append(keyQuery); |
2801 | 2803 |
2802 if (catalog != null && !catalog.isEmpty()) { | 2804 if (catalog != null && !catalog.isEmpty()) { |
2803 // none empty catalog selection. | 2805 // none empty catalog selection. |
2804 // as we do not support catalogs this always results in no rows returned | 2806 // as we do not support catalogs this always results in no rows returned |
2876 * @return ResultSet each row is a foreign key column description | 2878 * @return ResultSet each row is a foreign key column description |
2877 * @see #getImportedKeys | 2879 * @see #getImportedKeys |
2878 * @throws SQLException if a database error occurs | 2880 * @throws SQLException if a database error occurs |
2879 */ | 2881 */ |
2880 @Override | 2882 @Override |
2881 public ResultSet getExportedKeys(String catalog, String schema, String table) | 2883 public ResultSet getExportedKeys( |
2882 throws SQLException | 2884 final String catalog, |
2885 final String schema, | |
2886 final String table | |
2887 ) throws SQLException | |
2883 { | 2888 { |
2884 StringBuilder query = new StringBuilder(keyQuery.length() + 250); | 2889 final StringBuilder query = new StringBuilder(keyQuery.length() + 250); |
2885 query.append(keyQuery); | 2890 query.append(keyQuery); |
2886 | 2891 |
2887 if (catalog != null && !catalog.isEmpty()) { | 2892 if (catalog != null && !catalog.isEmpty()) { |
2888 // none empty catalog selection. | 2893 // none empty catalog selection. |
2889 // as we do not support catalogs this always results in no rows returned | 2894 // as we do not support catalogs this always results in no rows returned |
2969 * @throws SQLException if a database error occurs | 2974 * @throws SQLException if a database error occurs |
2970 * @see #getImportedKeys | 2975 * @see #getImportedKeys |
2971 */ | 2976 */ |
2972 @Override | 2977 @Override |
2973 public ResultSet getCrossReference( | 2978 public ResultSet getCrossReference( |
2974 String pcatalog, | 2979 final String pcatalog, |
2975 String pschema, | 2980 final String pschema, |
2976 String ptable, | 2981 final String ptable, |
2977 String fcatalog, | 2982 final String fcatalog, |
2978 String fschema, | 2983 final String fschema, |
2979 String ftable | 2984 final String ftable |
2980 ) throws SQLException | 2985 ) throws SQLException |
2981 { | 2986 { |
2982 StringBuilder query = new StringBuilder(keyQuery.length() + 350); | 2987 final StringBuilder query = new StringBuilder(keyQuery.length() + 350); |
2983 query.append(keyQuery); | 2988 query.append(keyQuery); |
2984 | 2989 |
2985 if ((pcatalog != null && !pcatalog.isEmpty()) | 2990 if ((pcatalog != null && !pcatalog.isEmpty()) |
2986 || (fcatalog != null && !fcatalog.isEmpty())) { | 2991 || (fcatalog != null && !fcatalog.isEmpty())) { |
2987 // none empty catalog selection. | 2992 // none empty catalog selection. |
3059 * @return ResultSet each row is a SQL type description | 3064 * @return ResultSet each row is a SQL type description |
3060 * @throws SQLException if a database error occurs | 3065 * @throws SQLException if a database error occurs |
3061 */ | 3066 */ |
3062 @Override | 3067 @Override |
3063 public ResultSet getTypeInfo() throws SQLException { | 3068 public ResultSet getTypeInfo() throws SQLException { |
3064 StringBuilder query = new StringBuilder(2300); | 3069 final StringBuilder query = new StringBuilder(2300); |
3065 query.append("SELECT \"sqlname\" AS \"TYPE_NAME\", " + | 3070 query.append("SELECT \"sqlname\" AS \"TYPE_NAME\", " + |
3066 "cast(").append(MonetDriver.getSQLTypeMap("\"sqlname\"")).append(" AS int) AS \"DATA_TYPE\", " + | 3071 "cast(").append(MonetDriver.getSQLTypeMap("\"sqlname\"")).append(" AS int) AS \"DATA_TYPE\", " + |
3067 "\"digits\" AS \"PRECISION\", " + // note that when radix is 2 the precision shows the number of bits | 3072 "\"digits\" AS \"PRECISION\", " + // note that when radix is 2 the precision shows the number of bits |
3068 "cast(CASE WHEN \"systemname\" IN ('str','inet','json','url','uuid','blob','sqlblob') THEN ''''" + | 3073 "cast(CASE WHEN \"systemname\" IN ('str','inet','json','url','uuid','blob','sqlblob') THEN ''''" + |
3069 " ELSE NULL END AS varchar(2)) AS \"LITERAL_PREFIX\", " + | 3074 " ELSE NULL END AS varchar(2)) AS \"LITERAL_PREFIX\", " + |
3146 * @return ResultSet each row is an index column description | 3151 * @return ResultSet each row is an index column description |
3147 * @throws SQLException if a database occurs | 3152 * @throws SQLException if a database occurs |
3148 */ | 3153 */ |
3149 @Override | 3154 @Override |
3150 public ResultSet getIndexInfo( | 3155 public ResultSet getIndexInfo( |
3151 String catalog, | 3156 final String catalog, |
3152 String schema, | 3157 final String schema, |
3153 String table, | 3158 final String table, |
3154 boolean unique, | 3159 final boolean unique, |
3155 boolean approximate | 3160 final boolean approximate |
3156 ) throws SQLException | 3161 ) throws SQLException |
3157 { | 3162 { |
3158 String table_row_count = "0"; | 3163 String table_row_count = "0"; |
3159 | 3164 |
3160 if (!approximate && schema != null && table != null && !schema.isEmpty() && !table.isEmpty()) { | 3165 if (!approximate && schema != null && table != null && !schema.isEmpty() && !table.isEmpty()) { |
3176 } catch (SQLException e) { /* ignore */ } | 3181 } catch (SQLException e) { /* ignore */ } |
3177 } | 3182 } |
3178 } | 3183 } |
3179 } | 3184 } |
3180 | 3185 |
3181 StringBuilder query = new StringBuilder(1250); | 3186 final StringBuilder query = new StringBuilder(1250); |
3182 query.append( | 3187 query.append( |
3183 "SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + | 3188 "SELECT cast(null AS char(1)) AS \"TABLE_CAT\", " + |
3184 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + | 3189 "\"schemas\".\"name\" AS \"TABLE_SCHEM\", " + |
3185 "\"tables\".\"name\" AS \"TABLE_NAME\", " + | 3190 "\"tables\".\"name\" AS \"TABLE_NAME\", " + |
3186 "CASE WHEN \"keys\".\"name\" IS NULL THEN true ELSE false END AS \"NON_UNIQUE\", " + | 3191 "CASE WHEN \"keys\".\"name\" IS NULL THEN true ELSE false END AS \"NON_UNIQUE\", " + |
3234 * @param type - defined in java.sql.ResultSet | 3239 * @param type - defined in java.sql.ResultSet |
3235 * @return true if so; false otherwise | 3240 * @return true if so; false otherwise |
3236 * @throws SQLException - if a database access error occurs | 3241 * @throws SQLException - if a database access error occurs |
3237 */ | 3242 */ |
3238 @Override | 3243 @Override |
3239 public boolean supportsResultSetType(int type) throws SQLException { | 3244 public boolean supportsResultSetType(final int type) throws SQLException { |
3240 // The only type we don't support | 3245 // The only type we don't support |
3241 return type != ResultSet.TYPE_SCROLL_SENSITIVE; | 3246 return type != ResultSet.TYPE_SCROLL_SENSITIVE; |
3242 } | 3247 } |
3243 | 3248 |
3244 | 3249 |
3250 * @param concurrency - type defined in java.sql.ResultSet | 3255 * @param concurrency - type defined in java.sql.ResultSet |
3251 * @return true if so; false otherwise | 3256 * @return true if so; false otherwise |
3252 * @throws SQLException - if a database access error occurs | 3257 * @throws SQLException - if a database access error occurs |
3253 */ | 3258 */ |
3254 @Override | 3259 @Override |
3255 public boolean supportsResultSetConcurrency(int type, int concurrency) | 3260 public boolean supportsResultSetConcurrency(final int type, final int concurrency) |
3256 throws SQLException | 3261 throws SQLException |
3257 { | 3262 { |
3258 // These combinations are not supported! | 3263 // These combinations are not supported! |
3259 if (type == ResultSet.TYPE_SCROLL_SENSITIVE) | 3264 if (type == ResultSet.TYPE_SCROLL_SENSITIVE) |
3260 return false; | 3265 return false; |
3268 } | 3273 } |
3269 | 3274 |
3270 | 3275 |
3271 /* lots of unsupported stuff... (no updatable ResultSet!) */ | 3276 /* lots of unsupported stuff... (no updatable ResultSet!) */ |
3272 @Override | 3277 @Override |
3273 public boolean ownUpdatesAreVisible(int type) { | 3278 public boolean ownUpdatesAreVisible(final int type) { |
3274 return false; | 3279 return false; |
3275 } | 3280 } |
3276 | 3281 |
3277 @Override | 3282 @Override |
3278 public boolean ownDeletesAreVisible(int type) { | 3283 public boolean ownDeletesAreVisible(final int type) { |
3279 return false; | 3284 return false; |
3280 } | 3285 } |
3281 | 3286 |
3282 @Override | 3287 @Override |
3283 public boolean ownInsertsAreVisible(int type) { | 3288 public boolean ownInsertsAreVisible(final int type) { |
3284 return false; | 3289 return false; |
3285 } | 3290 } |
3286 | 3291 |
3287 @Override | 3292 @Override |
3288 public boolean othersUpdatesAreVisible(int type) { | 3293 public boolean othersUpdatesAreVisible(final int type) { |
3289 return false; | 3294 return false; |
3290 } | 3295 } |
3291 | 3296 |
3292 @Override | 3297 @Override |
3293 public boolean othersDeletesAreVisible(int i) { | 3298 public boolean othersDeletesAreVisible(final int i) { |
3294 return false; | 3299 return false; |
3295 } | 3300 } |
3296 | 3301 |
3297 @Override | 3302 @Override |
3298 public boolean othersInsertsAreVisible(int type) { | 3303 public boolean othersInsertsAreVisible(final int type) { |
3299 return false; | 3304 return false; |
3300 } | 3305 } |
3301 | 3306 |
3302 @Override | 3307 @Override |
3303 public boolean updatesAreDetected(int type) { | 3308 public boolean updatesAreDetected(final int type) { |
3304 return false; | 3309 return false; |
3305 } | 3310 } |
3306 | 3311 |
3307 @Override | 3312 @Override |
3308 public boolean deletesAreDetected(int i) { | 3313 public boolean deletesAreDetected(final int i) { |
3309 return false; | 3314 return false; |
3310 } | 3315 } |
3311 | 3316 |
3312 @Override | 3317 @Override |
3313 public boolean insertsAreDetected(int type) { | 3318 public boolean insertsAreDetected(final int type) { |
3314 return false; | 3319 return false; |
3315 } | 3320 } |
3316 | 3321 |
3317 /** | 3322 /** |
3318 * Indicates whether the driver supports batch updates. | 3323 * Indicates whether the driver supports batch updates. |
3343 * | 3348 * |
3344 * @throws SQLException - if a database access error occurs | 3349 * @throws SQLException - if a database access error occurs |
3345 */ | 3350 */ |
3346 @Override | 3351 @Override |
3347 public ResultSet getUDTs( | 3352 public ResultSet getUDTs( |
3348 String catalog, | 3353 final String catalog, |
3349 String schemaPattern, | 3354 final String schemaPattern, |
3350 String typeNamePattern, | 3355 final String typeNamePattern, |
3351 int[] types | 3356 final int[] types |
3352 ) throws SQLException | 3357 ) throws SQLException |
3353 { | 3358 { |
3354 StringBuilder query = new StringBuilder(990); | 3359 final StringBuilder query = new StringBuilder(990); |
3355 if (types != null && types.length > 0) { | 3360 if (types != null && types.length > 0) { |
3356 query.append("SELECT * FROM ("); | 3361 query.append("SELECT * FROM ("); |
3357 } | 3362 } |
3358 query.append("SELECT cast(null as char(1)) AS \"TYPE_CAT\", " + | 3363 query.append("SELECT cast(null as char(1)) AS \"TYPE_CAT\", " + |
3359 "\"schemas\".\"name\" AS \"TYPE_SCHEM\", " + | 3364 "\"schemas\".\"name\" AS \"TYPE_SCHEM\", " + |
3412 public Connection getConnection() { | 3417 public Connection getConnection() { |
3413 return con; | 3418 return con; |
3414 } | 3419 } |
3415 | 3420 |
3416 /* I don't find these in the spec!?! */ | 3421 /* I don't find these in the spec!?! */ |
3417 public boolean rowChangesAreDetected(int type) { | 3422 public boolean rowChangesAreDetected(final int type) { |
3418 return false; | 3423 return false; |
3419 } | 3424 } |
3420 | 3425 |
3421 public boolean rowChangesAreVisible(int type) { | 3426 public boolean rowChangesAreVisible(final int type) { |
3422 return false; | 3427 return false; |
3423 } | 3428 } |
3424 | 3429 |
3425 //== 1.4 methods (JDBC 3) | 3430 //== 1.4 methods (JDBC 3) |
3426 | 3431 |
3510 * about the designated UDT | 3515 * about the designated UDT |
3511 * @throws SQLException if a database access error occurs | 3516 * @throws SQLException if a database access error occurs |
3512 */ | 3517 */ |
3513 @Override | 3518 @Override |
3514 public ResultSet getSuperTypes( | 3519 public ResultSet getSuperTypes( |
3515 String catalog, | 3520 final String catalog, |
3516 String schemaPattern, | 3521 final String schemaPattern, |
3517 String typeNamePattern | 3522 final String typeNamePattern |
3518 ) throws SQLException | 3523 ) throws SQLException |
3519 { | 3524 { |
3520 String query = | 3525 final String query = |
3521 "SELECT cast(null as char(1)) AS \"TYPE_CAT\", '' AS \"TYPE_SCHEM\", '' AS \"TYPE_NAME\", " + | 3526 "SELECT cast(null as char(1)) AS \"TYPE_CAT\", '' AS \"TYPE_SCHEM\", '' AS \"TYPE_NAME\", " + |
3522 "cast(null as char(1)) AS \"SUPERTYPE_CAT\", '' AS \"SUPERTYPE_SCHEM\", '' AS \"SUPERTYPE_NAME\" " + | 3527 "cast(null as char(1)) AS \"SUPERTYPE_CAT\", '' AS \"SUPERTYPE_SCHEM\", '' AS \"SUPERTYPE_NAME\" " + |
3523 "WHERE 1 = 0"; | 3528 "WHERE 1 = 0"; |
3524 | 3529 |
3525 return executeMetaDataQuery(query); | 3530 return executeMetaDataQuery(query); |
3555 * @return a <code>ResultSet</code> object in which each row is a type description | 3560 * @return a <code>ResultSet</code> object in which each row is a type description |
3556 * @throws SQLException if a database access error occurs | 3561 * @throws SQLException if a database access error occurs |
3557 */ | 3562 */ |
3558 @Override | 3563 @Override |
3559 public ResultSet getSuperTables( | 3564 public ResultSet getSuperTables( |
3560 String catalog, | 3565 final String catalog, |
3561 String schemaPattern, | 3566 final String schemaPattern, |
3562 String tableNamePattern | 3567 final String tableNamePattern |
3563 ) throws SQLException | 3568 ) throws SQLException |
3564 { | 3569 { |
3565 String query = | 3570 final String query = |
3566 "SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 3571 "SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
3567 "'' AS \"TABLE_SCHEM\", '' AS \"TABLE_NAME\", '' AS \"SUPERTABLE_NAME\" " + | 3572 "'' AS \"TABLE_SCHEM\", '' AS \"TABLE_NAME\", '' AS \"SUPERTABLE_NAME\" " + |
3568 "WHERE 1 = 0"; | 3573 "WHERE 1 = 0"; |
3569 | 3574 |
3570 return executeMetaDataQuery(query); | 3575 return executeMetaDataQuery(query); |
3639 * attribute description | 3644 * attribute description |
3640 * @throws SQLException if a database access error occurs | 3645 * @throws SQLException if a database access error occurs |
3641 */ | 3646 */ |
3642 @Override | 3647 @Override |
3643 public ResultSet getAttributes( | 3648 public ResultSet getAttributes( |
3644 String catalog, | 3649 final String catalog, |
3645 String schemaPattern, | 3650 final String schemaPattern, |
3646 String typeNamePattern, | 3651 final String typeNamePattern, |
3647 String attributeNamePattern | 3652 final String attributeNamePattern |
3648 ) throws SQLException | 3653 ) throws SQLException |
3649 { | 3654 { |
3650 String query = | 3655 final String query = |
3651 "SELECT cast(null as char(1)) AS \"TYPE_CAT\", '' AS \"TYPE_SCHEM\", '' AS \"TYPE_NAME\", " + | 3656 "SELECT cast(null as char(1)) AS \"TYPE_CAT\", '' AS \"TYPE_SCHEM\", '' AS \"TYPE_NAME\", " + |
3652 "'' AS \"ATTR_NAME\", cast(0 as int) AS \"DATA_TYPE\", '' AS \"ATTR_TYPE_NAME\", cast(0 as int) AS \"ATTR_SIZE\", " + | 3657 "'' AS \"ATTR_NAME\", cast(0 as int) AS \"DATA_TYPE\", '' AS \"ATTR_TYPE_NAME\", cast(0 as int) AS \"ATTR_SIZE\", " + |
3653 "cast(0 as int) AS \"DECIMAL_DIGITS\", cast(0 as int) AS \"NUM_PREC_RADIX\", cast(0 as int) AS \"NULLABLE\", " + | 3658 "cast(0 as int) AS \"DECIMAL_DIGITS\", cast(0 as int) AS \"NUM_PREC_RADIX\", cast(0 as int) AS \"NULLABLE\", " + |
3654 "'' AS \"REMARKS\", '' AS \"ATTR_DEF\", cast(0 as int) AS \"SQL_DATA_TYPE\", " + | 3659 "'' AS \"REMARKS\", '' AS \"ATTR_DEF\", cast(0 as int) AS \"SQL_DATA_TYPE\", " + |
3655 "cast(0 as int) AS \"SQL_DATETIME_SUB\", cast(0 as int) AS \"CHAR_OCTET_LENGTH\", " + | 3660 "cast(0 as int) AS \"SQL_DATETIME_SUB\", cast(0 as int) AS \"CHAR_OCTET_LENGTH\", " + |
3669 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code> | 3674 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code> |
3670 * @return <code>true</code> if so; <code>false</code> otherwise | 3675 * @return <code>true</code> if so; <code>false</code> otherwise |
3671 * @see Connection | 3676 * @see Connection |
3672 */ | 3677 */ |
3673 @Override | 3678 @Override |
3674 public boolean supportsResultSetHoldability(int holdability) { | 3679 public boolean supportsResultSetHoldability(final int holdability) { |
3675 // we don't close ResultSets at commit; and we don't do updateable | 3680 // we don't close ResultSets at commit; and we don't do updateable |
3676 // result sets, so comes closest to hold cursors over commit | 3681 // result sets, so comes closest to hold cursors over commit |
3677 return holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT; | 3682 return holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT; |
3678 } | 3683 } |
3679 | 3684 |
3879 * @throws SQLException if a database access error occurs | 3884 * @throws SQLException if a database access error occurs |
3880 */ | 3885 */ |
3881 @Override | 3886 @Override |
3882 public ResultSet getClientInfoProperties() throws SQLException { | 3887 public ResultSet getClientInfoProperties() throws SQLException { |
3883 // for a list of connection properties see also MonetConnection.java constructor MonetConnection(Properties props) | 3888 // for a list of connection properties see also MonetConnection.java constructor MonetConnection(Properties props) |
3884 String query = | 3889 final String query = |
3885 "SELECT 'host' AS \"NAME\", cast(1024 as int) AS \"MAX_LEN\", 'localhost' AS \"DEFAULT_VALUE\", 'DSN or IP-address of machine running MonetDB' AS \"DESCRIPTION\" UNION ALL " + | 3890 "SELECT 'host' AS \"NAME\", cast(1024 as int) AS \"MAX_LEN\", 'localhost' AS \"DEFAULT_VALUE\", 'DSN or IP-address of machine running MonetDB' AS \"DESCRIPTION\" UNION ALL " + |
3886 "SELECT 'port', 5, '50000', 'communication port number of MonetDB server process' UNION ALL " + | 3891 "SELECT 'port', 5, '50000', 'communication port number of MonetDB server process' UNION ALL " + |
3887 "SELECT 'user', 1024, '', 'user name to login to MonetDB server' UNION ALL " + | 3892 "SELECT 'user', 1024, '', 'user name to login to MonetDB server' UNION ALL " + |
3888 "SELECT 'password', 128, '', 'password for user name to login to MonetDB server' UNION ALL " + | 3893 "SELECT 'password', 128, '', 'password for user name to login to MonetDB server' UNION ALL " + |
3889 "SELECT 'language', 16, 'sql', 'language (sql or mal) used to parse commands in MonetDB server' UNION ALL " + | 3894 "SELECT 'language', 16, 'sql', 'language (sql or mal) used to parse commands in MonetDB server' UNION ALL " + |
3941 * @return ResultSet - each row is a function description | 3946 * @return ResultSet - each row is a function description |
3942 * @throws SQLException if a database access error occurs | 3947 * @throws SQLException if a database access error occurs |
3943 */ | 3948 */ |
3944 @Override | 3949 @Override |
3945 public ResultSet getFunctions( | 3950 public ResultSet getFunctions( |
3946 String catalog, | 3951 final String catalog, |
3947 String schemaPattern, | 3952 final String schemaPattern, |
3948 String functionNamePattern) | 3953 final String functionNamePattern |
3949 throws SQLException | 3954 ) throws SQLException |
3950 { | 3955 { |
3951 boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); | 3956 final boolean useCommentsTable = ((MonetConnection)con).commentsTableExists(); |
3952 StringBuilder query = new StringBuilder(800); | 3957 final StringBuilder query = new StringBuilder(800); |
3953 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + | 3958 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + |
3954 "\"schemas\".\"name\" AS \"FUNCTION_SCHEM\", " + | 3959 "\"schemas\".\"name\" AS \"FUNCTION_SCHEM\", " + |
3955 "\"functions\".\"name\" AS \"FUNCTION_NAME\", ") | 3960 "\"functions\".\"name\" AS \"FUNCTION_NAME\", ") |
3956 .append(useCommentsTable ? "COALESCE(\"comments\".\"remark\", cast(\"functions\".\"func\" as varchar(9999)))" : "cast(\"functions\".\"func\" as varchar(9999))").append(" AS \"REMARKS\", " + | 3961 .append(useCommentsTable ? "COALESCE(\"comments\".\"remark\", cast(\"functions\".\"func\" as varchar(9999)))" : "cast(\"functions\".\"func\" as varchar(9999))").append(" AS \"REMARKS\", " + |
3957 "CASE \"functions\".\"type\"" + | 3962 "CASE \"functions\".\"type\"" + |
4049 * column or return type | 4054 * column or return type |
4050 * @throws SQLException - if a database access error occurs | 4055 * @throws SQLException - if a database access error occurs |
4051 */ | 4056 */ |
4052 @Override | 4057 @Override |
4053 public ResultSet getFunctionColumns( | 4058 public ResultSet getFunctionColumns( |
4054 String catalog, | 4059 final String catalog, |
4055 String schemaPattern, | 4060 final String schemaPattern, |
4056 String functionNamePattern, | 4061 final String functionNamePattern, |
4057 String columnNamePattern) | 4062 final String columnNamePattern |
4058 throws SQLException | 4063 ) throws SQLException |
4059 { | 4064 { |
4060 StringBuilder query = new StringBuilder(2600); | 4065 final StringBuilder query = new StringBuilder(2600); |
4061 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + | 4066 query.append("SELECT cast(null as char(1)) AS \"FUNCTION_CAT\", " + |
4062 "\"schemas\".\"name\" AS \"FUNCTION_SCHEM\", " + | 4067 "\"schemas\".\"name\" AS \"FUNCTION_SCHEM\", " + |
4063 "\"functions\".\"name\" AS \"FUNCTION_NAME\", " + | 4068 "\"functions\".\"name\" AS \"FUNCTION_NAME\", " + |
4064 "\"args\".\"name\" AS \"COLUMN_NAME\", " + | 4069 "\"args\".\"name\" AS \"COLUMN_NAME\", " + |
4065 "cast(CASE \"args\".\"inout\"" + | 4070 "cast(CASE \"args\".\"inout\"" + |
4150 * @return ResultSet where each row is a column description | 4155 * @return ResultSet where each row is a column description |
4151 * @throws SQLException if a database access error occurs | 4156 * @throws SQLException if a database access error occurs |
4152 */ | 4157 */ |
4153 @Override | 4158 @Override |
4154 public ResultSet getPseudoColumns( | 4159 public ResultSet getPseudoColumns( |
4155 String catalog, | 4160 final String catalog, |
4156 String schemaPattern, | 4161 final String schemaPattern, |
4157 String tableNamePattern, | 4162 final String tableNamePattern, |
4158 String columnNamePattern) | 4163 final String columnNamePattern |
4159 throws SQLException | 4164 ) throws SQLException |
4160 { | 4165 { |
4161 // MonetDB currently does not support pseudo or hidden columns, so return an empty ResultSet | 4166 // MonetDB currently does not support pseudo or hidden columns, so return an empty ResultSet |
4162 String query = | 4167 final String query = |
4163 "SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + | 4168 "SELECT cast(null as char(1)) AS \"TABLE_CAT\", " + |
4164 "'' AS \"TABLE_SCHEM\", " + | 4169 "'' AS \"TABLE_SCHEM\", " + |
4165 "'' AS \"TABLE_NAME\", " + | 4170 "'' AS \"TABLE_NAME\", " + |
4166 "'' AS \"COLUMN_NAME\", " + | 4171 "'' AS \"COLUMN_NAME\", " + |
4167 "cast(0 as int) AS \"DATA_TYPE\", " + | 4172 "cast(0 as int) AS \"DATA_TYPE\", " + |