Q:

How to list partition-pruned inputs for Hive tables? 

I am using Spark SQL to query data in Hive.  The data is partitioned and Spark SQL correctly prunes the partitions when querying. 
However, I need to list either the source tables along with partition filters or the specific input files (.inputFiles would be an obvious choice for this but it does not reflect pruning) for a given query in order to determine on which part of the data the computation will be taking place. 
The closest I was able to get was by calling df.queryExecution.executedPlan.collectLeaves().  This contains the relevant plan nodes as HiveTableScanExec instances.  However, this class is private[hive] for the org.apache.spark.sql.hive package.  I think the relevant fields are relation and partitionPruningPred. 
Is there any way to achieve this? 
Update: I was able to get the relevant information thanks to Jacek's suggestion and by using getHiveQlPartitions on the returned relation and providing partitionPruningPred as the parameter:
scan.findHiveTables(execPlan).flatMap(e => e.relation.getHiveQlPartitions(e.partitionPruningPred))

This contained all the data I needed, including the paths to all input files, properly partition pruned. 

A:

Well, you're asking for low-level details of the query execution and things are bumpy down there.  You've been warned :)
As you noted in your comment, all the execution information are in this private[hive] HiveTableScanExec. 
One way to get some insight into HiveTableScanExec physical operator (that is a Hive table at execution time) is to create a sort of backdoor in org.apache.spark.sql.hive package that is not private[hive]. 
package org.apache.spark.sql.hive

import org.apache.spark.sql.hive.execution. HiveTableScanExec
object scan {
  def findHiveTables(execPlan: org.apache.spark.sql.execution. SparkPlan) = execPlan.collect { case hiveTables: HiveTableScanExec => hiveTables }
}

Change the code to meet your needs. 
With the scan.findHiveTables, I usually use :paste -raw while in spark-shell to sneak into such "uncharted areas". 
You could then simply do the following:
scala> spark.version
res0: String = 2.4.0-SNAPSHOT

// Create a Hive table
import org.apache.spark.sql.types. StructType
spark.catalog.createTable(
  tableName = "h1",
  source = "hive", // <-- that makes for a Hive table
  schema = new StructType().add($"id".long),
  options = Map.empty[String, String])

// select * from h1
val q = spark.table("h1")
val execPlan = q.queryExecution.executedPlan
scala> println(execPlan.numberedTreeString)
00 HiveTableScan [id#22L], HiveTableRelation `default`. `h1`, org.apache.hadoop.hive.serde2.lazy. LazySimpleSerDe, [id#22L]

// Use the above code and :paste -raw in spark-shell

import org.apache.spark.sql.hive.scan
scala> scan.findHiveTables(execPlan).size
res11: Int = 1

relation field is the Hive table after it's been resolved using ResolveRelations and FindDataSourceTable logical rule that Spark analyzer uses to resolve data source and hive tables. 
You can get pretty much all the information Spark uses from a Hive metastore using ExternalCatalog interface that is available as spark.sharedState.externalCatalog.  That gives you pretty much all the metadata Spark uses to plan queries over Hive tables.