Skip to content
Open
3 changes: 2 additions & 1 deletion src/main/java/org/sqlite/core/CoreDatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ protected String escape(final String val) {

/**
* Returns line without changes or with escaped schema prefix
*
* @param schema schema name
* @param line of text to prepend to
* @return The SQL escaped schema name with dot or empty string
Expand All @@ -200,6 +201,7 @@ protected String prependSchemaPrefix(String schema, String line) {

/**
* Adds line without changes or with escaped schema prefix
*
* @param sql String builder for sql request
* @param schema schema name
* @param line line to prepend schema prefix to
Expand All @@ -212,7 +214,6 @@ protected void prependSchemaPrefix(StringBuilder sql, String schema, String line
}
}


// inner classes

/** Pattern used to extract column order for an unnamed primary key. */
Expand Down
114 changes: 73 additions & 41 deletions src/main/java/org/sqlite/jdbc3/JDBC3DatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,9 @@ public ResultSet getColumns(String c, String s, String tblNamePattern, String co
checkOpen();

StringBuilder sql = new StringBuilder(700);
sql.append("select null as TABLE_CAT, ").append(quote(s)).append(" as TABLE_SCHEM, tblname as TABLE_NAME, ")
sql.append("select null as TABLE_CAT, ")
.append(quote(s == null ? "main" : s))
.append(" as TABLE_SCHEM, tblname as TABLE_NAME, ")
Comment on lines +967 to +968
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about that.

The function should return the actual schema of the table, no? But it seems we just feed back the parameter that was passed.

If we have 2 tables with the same name in 2 different schemas, and we call this function without specifying the schema s, then that function should return columns from both tables, but we would need to have TABLE_SCHEM to differentiate them.

.append(
"cn as COLUMN_NAME, ct as DATA_TYPE, tn as TYPE_NAME, colSize as COLUMN_SIZE, ")
.append(
Expand Down Expand Up @@ -948,10 +950,13 @@ public ResultSet getColumns(String c, String s, String tblNamePattern, String co
ResultSet rsColAutoinc = null;
try {
statColAutoinc = conn.createStatement();
rsColAutoinc = statColAutoinc.executeQuery(
"SELECT LIKE('%autoincrement%', LOWER(sql)) FROM " + prependSchemaPrefix(s,
"sqlite_master WHERE LOWER(name) = LOWER('") + escape(tableName)
+ "') AND TYPE IN ('table', 'view')");
rsColAutoinc =
statColAutoinc.executeQuery(
"SELECT LIKE('%autoincrement%', LOWER(sql)) FROM "
+ prependSchemaPrefix(
s, "sqlite_master WHERE LOWER(name) = LOWER('")
+ escape(tableName)
+ "') AND TYPE IN ('table', 'view')");
rsColAutoinc.next();
isAutoIncrement = rsColAutoinc.getInt(1) == 1;
} finally {
Expand All @@ -972,8 +977,10 @@ public ResultSet getColumns(String c, String s, String tblNamePattern, String co
}

// For each table, get the column info and build into overall SQL
String pragmaStatement = "PRAGMA " + prependSchemaPrefix(s, "table_xinfo('" + escape(tableName) +
"')");
String pragmaStatement =
"PRAGMA "
+ prependSchemaPrefix(
s, "table_xinfo('" + escape(tableName) + "')");
try (Statement colstat = conn.createStatement();
ResultSet rscol = colstat.executeQuery(pragmaStatement)) {

Expand Down Expand Up @@ -1172,8 +1179,9 @@ public ResultSet getCrossReference(
/** @see java.sql.DatabaseMetaData#getSchemas() */
public ResultSet getSchemas() throws SQLException {
if (getSchemas == null) {
getSchemas = conn.prepareStatement(
"select name as TABLE_SCHEM, null as TABLE_CATALOG from pragma_database_list;");
getSchemas =
conn.prepareStatement(
"select name as TABLE_SCHEM, null as TABLE_CATALOG from pragma_database_list;");
}

return getSchemas.executeQuery();
Expand All @@ -1198,7 +1206,9 @@ public ResultSet getPrimaryKeys(String c, String s, String table) throws SQLExce

Statement stat = conn.createStatement();
StringBuilder sql = new StringBuilder(512);
sql.append("select null as TABLE_CAT, ").append(quote(s)).append(" as TABLE_SCHEM, '")
sql.append("select null as TABLE_CAT, ")
.append(quote(s == null ? "main" : s))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar as above, we should return the actual schema of the retrieved PK's table, not the parameter that was passed to the function

.append(" as TABLE_SCHEM, '")
.append(escape(table))
.append("' as TABLE_NAME, cn as COLUMN_NAME, ks as KEY_SEQ, pk as PK_NAME from (");

Expand Down Expand Up @@ -1249,7 +1259,7 @@ public ResultSet getExportedKeys(String catalog, String schema, String table)

catalog = (catalog != null) ? quote(catalog) : null;

String quotedSchema = (schema != null) ? quote(schema) : null;
String quotedSchema = (schema != null) ? quote(schema) : quote("main");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar as above, we should return the actual schema of the retrieved PK's table, not the parameter that was passed to the function


StringBuilder exportedKeysQuery = new StringBuilder(512);

Expand All @@ -1258,11 +1268,11 @@ public ResultSet getExportedKeys(String catalog, String schema, String table)
if (pkColumns != null) {
// retrieve table list
ArrayList<String> tableList;
try (
ResultSet rs = stat.executeQuery(
"select name from " + prependSchemaPrefix(schema, "sqlite_master where type = " +
"'table'"))
) {
try (ResultSet rs =
stat.executeQuery(
"select name from "
+ prependSchemaPrefix(
schema, "sqlite_master where type = " + "'table'"))) {
tableList = new ArrayList<>();

while (rs.next()) {
Expand Down Expand Up @@ -1406,12 +1416,12 @@ public ResultSet getImportedKeys(String catalog, String schema, String table)
sql.append("select ")
.append(quote(catalog))
.append(" as PKTABLE_CAT, ")
.append(quote(schema))
.append(quote(schema == null ? "main" : schema))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar as above, we should return the actual schema of the retrieved PK's table, not the parameter that was passed to the function

.append(" as PKTABLE_SCHEM, ")
.append("ptn as PKTABLE_NAME, pcn as PKCOLUMN_NAME, ")
.append(quote(catalog))
.append(" as FKTABLE_CAT, ")
.append(quote(schema))
.append(quote(schema == null ? "main" : schema))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar as above, we should return the actual schema of the retrieved PK's table, not the parameter that was passed to the function

.append(" as FKTABLE_SCHEM, ")
.append(quote(table))
.append(" as FKTABLE_NAME, ")
Expand Down Expand Up @@ -1526,7 +1536,7 @@ public ResultSet getIndexInfo(String c, String s, String table, boolean u, boole
// define the column header
// this is from the JDBC spec, it is part of the driver protocol
sql.append("select null as TABLE_CAT,")
.append(quote(s))
.append(quote(s == null ? "main" : s))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar as above, we should return the actual schema of the retrieved PK's table, not the parameter that was passed to the function

.append(" as TABLE_SCHEM, '")
.append(escape(table))
.append(
Expand All @@ -1537,7 +1547,9 @@ public ResultSet getIndexInfo(String c, String s, String table, boolean u, boole
"cn as COLUMN_NAME, null as ASC_OR_DESC, 0 as CARDINALITY, 0 as PAGES, null as FILTER_CONDITION from (");

// this always returns a result set now, previously threw exception
rs = stat.executeQuery("pragma " + prependSchemaPrefix(s, "index_list('" + escape(table) + "');"));
rs =
stat.executeQuery(
"pragma " + prependSchemaPrefix(s, "index_list('" + escape(table) + "');"));

ArrayList<ArrayList<Object>> indexList = new ArrayList<>();
while (rs.next()) {
Expand All @@ -1561,7 +1573,11 @@ public ResultSet getIndexInfo(String c, String s, String table, boolean u, boole
while (indexIterator.hasNext()) {
currentIndex = indexIterator.next();
String indexName = currentIndex.get(0).toString();
rs = stat.executeQuery("pragma " + prependSchemaPrefix(s, "index_info('" + escape(indexName) + "');"));
rs =
stat.executeQuery(
"pragma "
+ prependSchemaPrefix(
s, "index_info('" + escape(indexName) + "');"));

while (rs.next()) {

Expand Down Expand Up @@ -1689,7 +1705,10 @@ public synchronized ResultSet getTables(
StringBuilder sql = new StringBuilder();
sql.append("SELECT").append("\n");
sql.append(" NULL AS TABLE_CAT,").append("\n");
sql.append(" NULL AS TABLE_SCHEM,").append("\n");
sql.append(" ")
.append(quote(s == null ? "main" : s))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar as above, we should return the actual schema of the retrieved PK's table, not the parameter that was passed to the function

.append(" AS TABLE_SCHEM,")
.append("\n");
sql.append(" NAME AS TABLE_NAME,").append("\n");
sql.append(" TYPE AS TABLE_TYPE,").append("\n");
sql.append(" NULL AS REMARKS,").append("\n");
Expand Down Expand Up @@ -1985,7 +2004,7 @@ public PrimaryKeyFinder(String table) throws SQLException {
/**
* Constructor.
*
* @param table The table for which to get find a primary key.
* @param table The table for which to get find a primary key.
* @param schema Schema in which table is located
* @throws SQLException
*/
Expand All @@ -2000,10 +2019,13 @@ public PrimaryKeyFinder(String table, String schema) throws SQLException {
// read create SQL script for table
ResultSet rs =
stat.executeQuery(
"select sql from " + prependSchemaPrefix(schema, "sqlite_master where"
+ " lower(name) = lower('"
+ escape(table)
+ "') and type in ('table', 'view')"))) {
"select sql from "
+ prependSchemaPrefix(
schema,
"sqlite_master where"
+ " lower(name) = lower('"
+ escape(table)
+ "') and type in ('table', 'view')"))) {

if (!rs.next()) throw new SQLException("Table not found: '" + table + "'");

Expand All @@ -2019,10 +2041,12 @@ public PrimaryKeyFinder(String table, String schema) throws SQLException {
}

if (pkColumns == null) {
try (
ResultSet rs2 = stat.executeQuery(
"pragma " + prependSchemaPrefix(schema, "table_info('" + escape(table) + "');"))
) {
try (ResultSet rs2 =
stat.executeQuery(
"pragma "
+ prependSchemaPrefix(
schema,
"table_info('" + escape(table) + "');"))) {
while (rs2.next()) {
if (rs2.getBoolean(6)) pkColumns = new String[] {rs2.getString(2)};
}
Expand Down Expand Up @@ -2073,13 +2097,15 @@ public ImportedKeyFinder(String table, String schema) throws SQLException {

List<String> fkNames = getForeignKeyNames(this.fkTableName, schema);

try (
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("pragma " + prependSchemaPrefix(
schema,
"foreign_key_list('" + escape(this.fkTableName.toLowerCase()) + "')"
))
) {
try (Statement stat = conn.createStatement();
ResultSet rs =
stat.executeQuery(
"pragma "
+ prependSchemaPrefix(
schema,
"foreign_key_list('"
+ escape(this.fkTableName.toLowerCase())
+ "')"))) {

int prevFkId = -1;
int count = 0;
Expand Down Expand Up @@ -2122,9 +2148,15 @@ private List<String> getForeignKeyNames(String tbl, String schema) throws SQLExc
return fkNames;
}
try (Statement stat2 = conn.createStatement();
ResultSet rs = stat2.executeQuery("select sql from " + prependSchemaPrefix(schema,
"sqlite_master where" + " lower(name) = lower('" + escape(tbl) + "')"
))) {
ResultSet rs =
stat2.executeQuery(
"select sql from "
+ prependSchemaPrefix(
schema,
"sqlite_master where"
+ " lower(name) = lower('"
+ escape(tbl)
+ "')"))) {
if (rs.next()) {
Matcher matcher = FK_NAMED_PATTERN.matcher(rs.getString(1));

Expand Down
Loading