Skip to content

Commit 838eaeb

Browse files
committed
Merge branch 'mkdirNewNewNewNewNewNewNewNew' into mkdirNewNewNewNewNewNewNewNewNew
# Conflicts: # sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
2 parents a6c7518 + b885f7b commit 838eaeb

File tree

4 files changed

+302
-99
lines changed

4 files changed

+302
-99
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SessionCatalog.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,12 @@ class SessionCatalog(
146146
currentDb = db
147147
}
148148

149-
def getDefaultDBPath(db: String): String = {
149+
/** Get the path for creating a non-default database. */
150+
def createDatabasePath(db: String, path: Option[String]): String = {
150151
val database = if (conf.caseSensitiveAnalysis) db else db.toLowerCase
151-
new Path(new Path(conf.warehousePath), database + ".db").toString
152+
path.map(new Path(_)).getOrElse {
153+
new Path(new Path(conf.warehousePath), database + ".db")
154+
}.toString
152155
}
153156

154157
// ----------------------------------------------------------------------------

sql/core/src/main/scala/org/apache/spark/sql/execution/command/ddl.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ import org.apache.spark.sql.types._
4040
* unless 'ifNotExists' is true.
4141
* The syntax of using this command in SQL is:
4242
* {{{
43-
* CREATE DATABASE|SCHEMA [IF NOT EXISTS] database_name
43+
* CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
44+
* [COMMENT database_comment]
45+
* [LOCATION database_directory]
46+
* [WITH DBPROPERTIES (property_name=property_value, ...)];
4447
* }}}
4548
*/
4649
case class CreateDatabase(
@@ -57,7 +60,7 @@ case class CreateDatabase(
5760
CatalogDatabase(
5861
databaseName,
5962
comment.getOrElse(""),
60-
path.getOrElse(catalog.getDefaultDBPath(databaseName)),
63+
catalog.createDatabasePath(databaseName, path),
6164
props),
6265
ifNotExists)
6366
Seq.empty[Row]

sql/core/src/test/scala/org/apache/spark/sql/execution/command/DDLSuite.scala

Lines changed: 162 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -95,49 +95,85 @@ class DDLSuite extends QueryTest with SharedSQLContext with BeforeAndAfterEach {
9595
catalog.createPartitions(tableName, Seq(part), ignoreIfExists = false)
9696
}
9797

98+
private def dropTable(catalog: SessionCatalog, name: TableIdentifier): Unit = {
99+
catalog.dropTable(name, ignoreIfNotExists = false)
100+
}
101+
102+
private def appendTrailingSlash(path: String): String = {
103+
if (!path.endsWith(File.separator)) path + File.separator else path
104+
}
105+
98106
test("the qualified path of a database is stored in the catalog") {
99107
val catalog = sqlContext.sessionState.catalog
100108

101-
val path = System.getProperty("java.io.tmpdir")
102-
// The generated temp path is not qualified.
103-
assert(!path.startsWith("file:/"))
104-
sql(s"CREATE DATABASE db1 LOCATION '$path'")
105-
val pathInCatalog = new Path(catalog.getDatabaseMetadata("db1").locationUri).toUri
106-
assert("file" === pathInCatalog.getScheme)
107-
assert(path === pathInCatalog.getPath)
108-
109-
withSQLConf(
110-
SQLConf.WAREHOUSE_PATH.key -> (System.getProperty("java.io.tmpdir"))) {
111-
sql(s"CREATE DATABASE db2")
112-
val pathInCatalog = new Path(catalog.getDatabaseMetadata("db2").locationUri).toUri
109+
withTempDir { tmpDir =>
110+
val path = tmpDir.toString
111+
// The generated temp path is not qualified.
112+
assert(!path.startsWith("file:/"))
113+
sql(s"CREATE DATABASE db1 LOCATION '$path'")
114+
val pathInCatalog = new Path(catalog.getDatabaseMetadata("db1").locationUri).toUri
113115
assert("file" === pathInCatalog.getScheme)
114-
assert(s"${sqlContext.conf.warehousePath}/db2.db" === pathInCatalog.getPath)
115-
}
116+
val expectedPath = if (path.endsWith(File.separator)) path.dropRight(1) else path
117+
assert(expectedPath === pathInCatalog.getPath)
118+
119+
withSQLConf(SQLConf.WAREHOUSE_PATH.key -> path) {
120+
sql(s"CREATE DATABASE db2")
121+
val pathInCatalog = new Path(catalog.getDatabaseMetadata("db2").locationUri).toUri
122+
assert("file" === pathInCatalog.getScheme)
123+
val expectedPath = appendTrailingSlash(sqlContext.conf.warehousePath) + "db2.db"
124+
assert(expectedPath === pathInCatalog.getPath)
125+
}
116126

117-
sql("DROP DATABASE db1")
118-
sql("DROP DATABASE db2")
127+
sql("DROP DATABASE db1")
128+
sql("DROP DATABASE db2")
129+
}
119130
}
120131

121132
test("Create/Drop Database") {
122-
withSQLConf(
123-
SQLConf.WAREHOUSE_PATH.key -> (System.getProperty("java.io.tmpdir") + File.separator)) {
124-
val catalog = sqlContext.sessionState.catalog
133+
withTempDir { tmpDir =>
134+
val path = tmpDir.toString
135+
withSQLConf(SQLConf.WAREHOUSE_PATH.key -> path) {
136+
val catalog = sqlContext.sessionState.catalog
137+
val databaseNames = Seq("db1", "`database`")
138+
139+
databaseNames.foreach { dbName =>
140+
try {
141+
val dbNameWithoutBackTicks = cleanIdentifier(dbName)
125142

126-
val databaseNames = Seq("db1", "`database`")
143+
sql(s"CREATE DATABASE $dbName")
144+
val db1 = catalog.getDatabaseMetadata(dbNameWithoutBackTicks)
145+
val expectedLocation =
146+
"file:" + appendTrailingSlash(path) + s"$dbNameWithoutBackTicks.db"
147+
assert(db1 == CatalogDatabase(
148+
dbNameWithoutBackTicks,
149+
"",
150+
expectedLocation,
151+
Map.empty))
152+
sql(s"DROP DATABASE $dbName CASCADE")
153+
assert(!catalog.databaseExists(dbNameWithoutBackTicks))
154+
} finally {
155+
catalog.reset()
156+
}
157+
}
158+
}
159+
}
160+
}
127161

162+
test("Create/Drop Database - location") {
163+
val catalog = sqlContext.sessionState.catalog
164+
val databaseNames = Seq("db1", "`database`")
165+
withTempDir { tmpDir =>
166+
val path = tmpDir.toString
167+
val dbPath = "file:" + path
128168
databaseNames.foreach { dbName =>
129169
try {
130170
val dbNameWithoutBackTicks = cleanIdentifier(dbName)
131-
132-
sql(s"CREATE DATABASE $dbName")
171+
sql(s"CREATE DATABASE $dbName Location '$path'")
133172
val db1 = catalog.getDatabaseMetadata(dbNameWithoutBackTicks)
134-
val expectedLocation =
135-
"file:" + System.getProperty("java.io.tmpdir") +
136-
File.separator + s"$dbNameWithoutBackTicks.db"
137173
assert(db1 == CatalogDatabase(
138174
dbNameWithoutBackTicks,
139175
"",
140-
expectedLocation,
176+
if (dbPath.endsWith(File.separator)) dbPath.dropRight(1) else dbPath,
141177
Map.empty))
142178
sql(s"DROP DATABASE $dbName CASCADE")
143179
assert(!catalog.databaseExists(dbNameWithoutBackTicks))
@@ -149,77 +185,78 @@ class DDLSuite extends QueryTest with SharedSQLContext with BeforeAndAfterEach {
149185
}
150186

151187
test("Create Database - database already exists") {
152-
withSQLConf(
153-
SQLConf.WAREHOUSE_PATH.key -> (System.getProperty("java.io.tmpdir") + File.separator)) {
154-
val catalog = sqlContext.sessionState.catalog
155-
val databaseNames = Seq("db1", "`database`")
156-
157-
databaseNames.foreach { dbName =>
158-
try {
159-
val dbNameWithoutBackTicks = cleanIdentifier(dbName)
160-
sql(s"CREATE DATABASE $dbName")
161-
val db1 = catalog.getDatabaseMetadata(dbNameWithoutBackTicks)
162-
val expectedLocation =
163-
"file:" + System.getProperty("java.io.tmpdir") +
164-
File.separator + s"$dbNameWithoutBackTicks.db"
165-
assert(db1 == CatalogDatabase(
166-
dbNameWithoutBackTicks,
167-
"",
168-
expectedLocation,
169-
Map.empty))
170-
171-
val message = intercept[AnalysisException] {
188+
withTempDir { tmpDir =>
189+
val path = tmpDir.toString
190+
withSQLConf(SQLConf.WAREHOUSE_PATH.key -> path) {
191+
val catalog = sqlContext.sessionState.catalog
192+
val databaseNames = Seq("db1", "`database`")
193+
194+
databaseNames.foreach { dbName =>
195+
try {
196+
val dbNameWithoutBackTicks = cleanIdentifier(dbName)
172197
sql(s"CREATE DATABASE $dbName")
173-
}.getMessage
174-
assert(message.contains(s"Database '$dbNameWithoutBackTicks' already exists."))
175-
} finally {
176-
catalog.reset()
198+
val db1 = catalog.getDatabaseMetadata(dbNameWithoutBackTicks)
199+
val expectedLocation =
200+
"file:" + appendTrailingSlash(path) + s"$dbNameWithoutBackTicks.db"
201+
assert(db1 == CatalogDatabase(
202+
dbNameWithoutBackTicks,
203+
"",
204+
expectedLocation,
205+
Map.empty))
206+
207+
val message = intercept[AnalysisException] {
208+
sql(s"CREATE DATABASE $dbName")
209+
}.getMessage
210+
assert(message.contains(s"Database '$dbNameWithoutBackTicks' already exists."))
211+
} finally {
212+
catalog.reset()
213+
}
177214
}
178215
}
179216
}
180217
}
181218

182219
test("Alter/Describe Database") {
183-
withSQLConf(
184-
SQLConf.WAREHOUSE_PATH.key -> (System.getProperty("java.io.tmpdir") + File.separator)) {
185-
val catalog = sqlContext.sessionState.catalog
186-
val databaseNames = Seq("db1", "`database`")
220+
withTempDir { tmpDir =>
221+
val path = tmpDir.toString
222+
withSQLConf(SQLConf.WAREHOUSE_PATH.key -> path) {
223+
val catalog = sqlContext.sessionState.catalog
224+
val databaseNames = Seq("db1", "`database`")
187225

188-
databaseNames.foreach { dbName =>
189-
try {
190-
val dbNameWithoutBackTicks = cleanIdentifier(dbName)
191-
val location =
192-
"file:" + System.getProperty("java.io.tmpdir") +
193-
File.separator + s"$dbNameWithoutBackTicks.db"
194-
195-
sql(s"CREATE DATABASE $dbName")
196-
197-
checkAnswer(
198-
sql(s"DESCRIBE DATABASE EXTENDED $dbName"),
199-
Row("Database Name", dbNameWithoutBackTicks) ::
200-
Row("Description", "") ::
201-
Row("Location", location) ::
202-
Row("Properties", "") :: Nil)
203-
204-
sql(s"ALTER DATABASE $dbName SET DBPROPERTIES ('a'='a', 'b'='b', 'c'='c')")
205-
206-
checkAnswer(
207-
sql(s"DESCRIBE DATABASE EXTENDED $dbName"),
208-
Row("Database Name", dbNameWithoutBackTicks) ::
209-
Row("Description", "") ::
210-
Row("Location", location) ::
211-
Row("Properties", "((a,a), (b,b), (c,c))") :: Nil)
212-
213-
sql(s"ALTER DATABASE $dbName SET DBPROPERTIES ('d'='d')")
214-
215-
checkAnswer(
216-
sql(s"DESCRIBE DATABASE EXTENDED $dbName"),
217-
Row("Database Name", dbNameWithoutBackTicks) ::
218-
Row("Description", "") ::
219-
Row("Location", location) ::
220-
Row("Properties", "((a,a), (b,b), (c,c), (d,d))") :: Nil)
221-
} finally {
222-
catalog.reset()
226+
databaseNames.foreach { dbName =>
227+
try {
228+
val dbNameWithoutBackTicks = cleanIdentifier(dbName)
229+
val location = "file:" + appendTrailingSlash(path) + s"$dbNameWithoutBackTicks.db"
230+
231+
sql(s"CREATE DATABASE $dbName")
232+
233+
checkAnswer(
234+
sql(s"DESCRIBE DATABASE EXTENDED $dbName"),
235+
Row("Database Name", dbNameWithoutBackTicks) ::
236+
Row("Description", "") ::
237+
Row("Location", location) ::
238+
Row("Properties", "") :: Nil)
239+
240+
sql(s"ALTER DATABASE $dbName SET DBPROPERTIES ('a'='a', 'b'='b', 'c'='c')")
241+
242+
checkAnswer(
243+
sql(s"DESCRIBE DATABASE EXTENDED $dbName"),
244+
Row("Database Name", dbNameWithoutBackTicks) ::
245+
Row("Description", "") ::
246+
Row("Location", location) ::
247+
Row("Properties", "((a,a), (b,b), (c,c))") :: Nil)
248+
249+
sql(s"ALTER DATABASE $dbName SET DBPROPERTIES ('d'='d')")
250+
251+
checkAnswer(
252+
sql(s"DESCRIBE DATABASE EXTENDED $dbName"),
253+
Row("Database Name", dbNameWithoutBackTicks) ::
254+
Row("Description", "") ::
255+
Row("Location", location) ::
256+
Row("Properties", "((a,a), (b,b), (c,c), (d,d))") :: Nil)
257+
} finally {
258+
catalog.reset()
259+
}
223260
}
224261
}
225262
}
@@ -251,7 +288,42 @@ class DDLSuite extends QueryTest with SharedSQLContext with BeforeAndAfterEach {
251288
}
252289
}
253290

254-
// TODO: test drop database in restrict mode
291+
test("drop non-empty database in restrict mode") {
292+
val catalog = sqlContext.sessionState.catalog
293+
val dbName = "db1"
294+
sql(s"CREATE DATABASE $dbName")
295+
296+
// create a table in database
297+
val tableIdent1 = TableIdentifier("tab1", Some(dbName))
298+
createTable(catalog, tableIdent1)
299+
300+
// drop a non-empty database in Restrict mode
301+
val message = intercept[AnalysisException] {
302+
sql(s"DROP DATABASE $dbName RESTRICT")
303+
}.getMessage
304+
assert(message.contains(s"Database '$dbName' is not empty. One or more tables exist"))
305+
306+
dropTable(catalog, tableIdent1)
307+
assert(catalog.listDatabases().contains(dbName))
308+
sql(s"DROP DATABASE $dbName RESTRICT")
309+
assert(!catalog.listDatabases().contains(dbName))
310+
}
311+
312+
test("drop non-empty database in cascade mode") {
313+
val catalog = sqlContext.sessionState.catalog
314+
val dbName = "db1"
315+
sql(s"CREATE DATABASE $dbName")
316+
317+
// create a table in database
318+
val tableIdent1 = TableIdentifier("tab1", Some(dbName))
319+
createTable(catalog, tableIdent1)
320+
321+
// drop a non-empty database in CASCADE mode
322+
assert(catalog.listTables(dbName).contains(tableIdent1))
323+
assert(catalog.listDatabases().contains(dbName))
324+
sql(s"DROP DATABASE $dbName CASCADE")
325+
assert(!catalog.listDatabases().contains(dbName))
326+
}
255327

256328
test("create table in default db") {
257329
val catalog = sqlContext.sessionState.catalog

0 commit comments

Comments
 (0)