@@ -22,7 +22,6 @@ import java.net.URI
2222import java .text .SimpleDateFormat
2323import java .util .{Date , Locale , Random }
2424
25- import org .apache .hadoop .conf .Configuration
2625import org .apache .hadoop .fs .{FileSystem , Path }
2726import org .apache .hadoop .hive .common .FileUtils
2827import org .apache .hadoop .hive .ql .exec .TaskRunner
@@ -86,14 +85,15 @@ case class InsertIntoHiveTable(
8685
8786 val hadoopConf = sessionState.newHadoopConf()
8887 val stagingDir = hadoopConf.get(" hive.exec.stagingdir" , " .hive-staging" )
88+ val scratchDir = hadoopConf.get(" hive.exec.scratchdir" , " /tmp/hive" )
8989
9090 private def executionId : String = {
9191 val rand : Random = new Random
9292 val format = new SimpleDateFormat (" yyyy-MM-dd_HH-mm-ss_SSS" , Locale .US )
9393 " hive_" + format.format(new Date ) + " _" + Math .abs(rand.nextLong)
9494 }
9595
96- private def getStagingDir (inputPath : Path , hadoopConf : Configuration ): Path = {
96+ private def getStagingDir (inputPath : Path ): Path = {
9797 val inputPathUri : URI = inputPath.toUri
9898 val inputPathName : String = inputPathUri.getPath
9999 val fs : FileSystem = inputPath.getFileSystem(hadoopConf)
@@ -121,21 +121,61 @@ case class InsertIntoHiveTable(
121121 return dir
122122 }
123123
124- private def getExternalScratchDir (extURI : URI , hadoopConf : Configuration ): Path = {
125- getStagingDir(new Path (extURI.getScheme, extURI.getAuthority, extURI.getPath), hadoopConf )
124+ private def getExternalScratchDir (extURI : URI ): Path = {
125+ getStagingDir(new Path (extURI.getScheme, extURI.getAuthority, extURI.getPath))
126126 }
127127
128- def getExternalTmpPath (path : Path , hadoopConf : Configuration ): Path = {
128+ def getExternalTmpPath (path : Path ): Path = {
129+ val hiveVersion = externalCatalog.asInstanceOf [HiveExternalCatalog ].client.version.fullVersion
130+ if (hiveVersion.startsWith(" 0.12" ) ||
131+ hiveVersion.startsWith(" 0.13" ) ||
132+ hiveVersion.startsWith(" 0.14" ) ||
133+ hiveVersion.startsWith(" 1.0" )) {
134+ oldStyleExternalTempPath(path)
135+ } else if (hiveVersion.startsWith(" 1.1" ) || hiveVersion.startsWith(" 1.2" )) {
136+ newStyleExternalTempPath(path)
137+ } else {
138+ throw new IllegalStateException (" Unsupported hive version: " + hiveVersion)
139+ }
140+ }
141+
142+ // Mostly copied from Context.java#getExternalTmpPath of Hive 0.13
143+ def oldStyleExternalTempPath (path : Path ): Path = {
144+ val extURI : URI = path.toUri
145+ val scratchPath = new Path (scratchDir, executionId)
146+ var dirPath = new Path (
147+ extURI.getScheme,
148+ extURI.getAuthority,
149+ scratchPath.toUri.getPath + " -" + TaskRunner .getTaskRunnerID())
150+
151+ try {
152+ val fs : FileSystem = dirPath.getFileSystem(hadoopConf)
153+ dirPath = new Path (fs.makeQualified(dirPath).toString())
154+
155+ if (! FileUtils .mkdir(fs, dirPath, true , hadoopConf)) {
156+ throw new IllegalStateException (" Cannot create staging directory: " + dirPath.toString)
157+ }
158+ fs.deleteOnExit(dirPath)
159+ } catch {
160+ case e : IOException =>
161+ throw new RuntimeException (" Cannot create staging directory: " + dirPath.toString, e)
162+
163+ }
164+ dirPath
165+ }
166+
167+ // Mostly copied from Context.java#getExternalTmpPath of Hive 1.2
168+ def newStyleExternalTempPath (path : Path ): Path = {
129169 val extURI : URI = path.toUri
130170 if (extURI.getScheme == " viewfs" ) {
131- getExtTmpPathRelTo(path.getParent, hadoopConf )
171+ getExtTmpPathRelTo(path.getParent)
132172 } else {
133- new Path (getExternalScratchDir(extURI, hadoopConf ), " -ext-10000" )
173+ new Path (getExternalScratchDir(extURI), " -ext-10000" )
134174 }
135175 }
136176
137- def getExtTmpPathRelTo (path : Path , hadoopConf : Configuration ): Path = {
138- new Path (getStagingDir(path, hadoopConf ), " -ext-10000" ) // Hive uses 10000
177+ def getExtTmpPathRelTo (path : Path ): Path = {
178+ new Path (getStagingDir(path), " -ext-10000" ) // Hive uses 10000
139179 }
140180
141181 private def saveAsHiveFile (
@@ -172,7 +212,7 @@ case class InsertIntoHiveTable(
172212 // instances within the closure, since Serializer is not serializable while TableDesc is.
173213 val tableDesc = table.tableDesc
174214 val tableLocation = table.hiveQlTable.getDataLocation
175- val tmpLocation = getExternalTmpPath(tableLocation, hadoopConf )
215+ val tmpLocation = getExternalTmpPath(tableLocation)
176216 val fileSinkConf = new FileSinkDesc (tmpLocation.toString, tableDesc, false )
177217 val isCompressed = hadoopConf.get(" hive.exec.compress.output" , " false" ).toBoolean
178218
0 commit comments