Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,29 @@ private static String escapeLiteral(String value) {

@Override
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
StringBuilder sql = new StringBuilder("SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, name AS TABLE_NAME, UPPER(type) AS TABLE_TYPE, NULL AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM, NULL AS TYPE_NAME, NULL AS SELF_REFERENCING_COL_NAME, NULL AS REF_GENERATION FROM sqlite_master WHERE 1=1");
if (tableNamePattern != null && !tableNamePattern.equals("%")) {
sql.append(" AND name LIKE '").append(escapeLiteral(tableNamePattern)).append("'");
String pattern = tableNamePattern == null || tableNamePattern.isEmpty()
? "%"
: escapeLiteral(tableNamePattern);
StringBuilder sql = new StringBuilder();
sql.append("SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, NAME AS TABLE_NAME, TYPE AS TABLE_TYPE, ")
.append("NULL AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM, NULL AS TYPE_NAME, ")
.append("NULL AS SELF_REFERENCING_COL_NAME, NULL AS REF_GENERATION FROM (")
.append("SELECT 'sqlite_schema' AS NAME, 'SYSTEM TABLE' AS TYPE")
.append(" UNION ALL SELECT NAME, UPPER(TYPE) AS TYPE FROM sqlite_schema")
.append(" WHERE NAME NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND UPPER(TYPE) IN ('TABLE', 'VIEW')")
.append(" UNION ALL SELECT NAME, 'GLOBAL TEMPORARY' AS TYPE FROM sqlite_temp_master")
.append(" UNION ALL SELECT NAME, 'SYSTEM TABLE' AS TYPE FROM sqlite_schema")
.append(" WHERE NAME LIKE 'sqlite\\_%' ESCAPE '\\'")
.append(") WHERE TABLE_NAME LIKE '").append(pattern).append("' ESCAPE '\\'");
if (types != null && types.length != 0) {
sql.append(" AND TABLE_TYPE IN (");
for (int i = 0; i < types.length; i++) {
if (i > 0) {
sql.append(",");
}
sql.append("'").append(escapeLiteral(types[i].toUpperCase())).append("'");
}
sql.append(")");
}
sql.append(" ORDER BY TABLE_TYPE, TABLE_NAME");
return executeMetadataQuery(sql.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,77 @@ void escapesSingleQuoteInTableNamePattern() throws SQLException {
ResultSet resultSet = metadata.getTables(null, null, "O'Brien", null);
resultSet.close();

assertThat(connection.lastSql).contains("name LIKE 'O''Brien'");
assertThat(connection.lastSql).doesNotContain("name LIKE 'O'Brien'");
assertThat(connection.lastSql).contains("TABLE_NAME LIKE 'O''Brien'");
assertThat(connection.lastSql).doesNotContain("TABLE_NAME LIKE 'O'Brien'");
}

@Test
void getTablesWithNullTypesReturnsOnlyTablesViewsAndSystemAndTemporaryRows() throws SQLException {
RecordingConnection connection = new RecordingConnection(emptyResult());

new LibsqlDatabaseMetaData(connection).getTables(null, null, null, null).close();

assertThat(connection.lastSql)
.contains("'sqlite_schema' AS NAME")
.contains("'SYSTEM TABLE' AS TYPE")
.contains("'GLOBAL TEMPORARY' AS TYPE")
.contains("FROM sqlite_temp_master")
.contains("UPPER(TYPE) IN ('TABLE', 'VIEW')")
.contains("TABLE_NAME LIKE '%'")
.doesNotContain("TABLE_TYPE IN")
.doesNotContain("INDEX")
.doesNotContain("TRIGGER");
}

@Test
void getTablesWithEmptyTypesBehavesLikeNullTypes() throws SQLException {
RecordingConnection connection = new RecordingConnection(emptyResult());

new LibsqlDatabaseMetaData(connection).getTables(null, null, null, new String[0]).close();

assertThat(connection.lastSql)
.contains("'SYSTEM TABLE' AS TYPE")
.contains("'GLOBAL TEMPORARY' AS TYPE")
.contains("UPPER(TYPE) IN ('TABLE', 'VIEW')")
.doesNotContain("TABLE_TYPE IN");
}

@Test
void getTablesWithTableTypeFiltersToTableRows() throws SQLException {
RecordingConnection connection = new RecordingConnection(emptyResult());

new LibsqlDatabaseMetaData(connection).getTables(null, null, null, new String[] {"TABLE"}).close();

assertThat(connection.lastSql)
.contains("UPPER(TYPE) IN ('TABLE', 'VIEW')")
.contains("AND TABLE_TYPE IN ('TABLE')");
}

@Test
void getTablesWithViewTypeFiltersToViewRows() throws SQLException {
RecordingConnection connection = new RecordingConnection(emptyResult());

new LibsqlDatabaseMetaData(connection).getTables(null, null, null, new String[] {"VIEW"}).close();

assertThat(connection.lastSql).contains("AND TABLE_TYPE IN ('VIEW')");
}

@Test
void getTablesWithMultipleTypesUppercasesThem() throws SQLException {
RecordingConnection connection = new RecordingConnection(emptyResult());

new LibsqlDatabaseMetaData(connection).getTables(null, null, null, new String[] {"table", "View"}).close();

assertThat(connection.lastSql).contains("AND TABLE_TYPE IN ('TABLE','VIEW')");
}

@Test
void getTablesWithEmptyTableNamePatternMatchesEverything() throws SQLException {
RecordingConnection connection = new RecordingConnection(emptyResult());

new LibsqlDatabaseMetaData(connection).getTables(null, null, "", null).close();

assertThat(connection.lastSql).contains("TABLE_NAME LIKE '%'");
}

private static StmtResult emptyResult() {
Expand Down
Loading