or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-driver.mdcli-services.mdindex.mdmetadata-operations.mdoperation-management.mdserver-management.mdsession-management.mdsql-execution.mdweb-ui.md

cli-driver.mddocs/

0

# CLI Driver

1

2

Interactive command-line interface with SQL completion, history management, signal handling, and comprehensive command processing for Spark SQL queries.

3

4

## Capabilities

5

6

### SparkSQLCLIDriver Object

7

8

Main entry point for the Spark SQL command-line interface with interactive and batch processing capabilities.

9

10

```scala { .api }

11

/**

12

* Main entry point for Spark SQL CLI with interactive shell capabilities

13

*/

14

object SparkSQLCLIDriver {

15

/**

16

* Command-line entry point for the CLI

17

* @param args Command line arguments including SQL files, configuration options

18

*/

19

def main(args: Array[String]): Unit

20

21

/**

22

* Install interrupt signal handler for Ctrl+C support

23

* Enables cancellation of running queries and graceful shutdown

24

*/

25

def installSignalHandler(): Unit

26

27

/**

28

* Print command-line usage information

29

*/

30

def printUsage(): Unit

31

32

/**

33

* Exit the CLI application with specified code

34

* @param code Exit code (0 for success, non-zero for error)

35

*/

36

def exit(code: Int): Unit

37

}

38

```

39

40

**Usage Examples:**

41

42

```bash

43

# Start interactive CLI

44

spark-sql

45

46

# Execute SQL file

47

spark-sql -f queries.sql

48

49

# Set Hive configuration

50

spark-sql --hiveconf hive.server2.thrift.port=10001

51

52

# Execute single statement

53

spark-sql -e "SELECT COUNT(*) FROM my_table"

54

55

# Enable verbose output

56

spark-sql --verbose

57

58

# Set variables

59

spark-sql --hivevar username=alice --hivevar threshold=100

60

```

61

62

### SparkSQLCLIDriver Class

63

64

Interactive CLI driver implementation with command processing and session management.

65

66

```scala { .api }

67

/**

68

* Interactive CLI driver for Spark SQL with Hive compatibility

69

*/

70

class SparkSQLCLIDriver extends CliDriver {

71

/**

72

* Process a SQL command or CLI directive

73

* @param cmd Command string to process

74

* @return 0 on success, non-zero on error

75

*/

76

def processCmd(cmd: String): Int

77

78

/**

79

* Process a line of input with optional interrupt handling

80

* @param line Input line containing one or more SQL statements

81

* @param allowInterrupting Whether to enable Ctrl+C interrupt handling

82

* @return 0 on success, non-zero on error

83

*/

84

def processLine(line: String, allowInterrupting: Boolean): Int

85

86

/**

87

* Print Spark master and application ID information

88

*/

89

def printMasterAndAppId(): Unit

90

91

/**

92

* Set Hive variables in the Spark SQL context

93

* @param hiveVariables Map of variable names to values

94

*/

95

def setHiveVariables(hiveVariables: java.util.Map[String, String]): Unit

96

}

97

```

98

99

**Usage Examples:**

100

101

```scala

102

import org.apache.spark.sql.hive.thriftserver.SparkSQLCLIDriver

103

104

// Create CLI driver instance

105

val cliDriver = new SparkSQLCLIDriver()

106

107

// Set variables

108

val variables = Map("database" -> "sales", "year" -> "2023").asJava

109

cliDriver.setHiveVariables(variables)

110

111

// Process commands

112

val result1 = cliDriver.processCmd("USE ${database}")

113

val result2 = cliDriver.processCmd("SELECT COUNT(*) FROM orders WHERE year = ${year}")

114

115

// Print connection info

116

cliDriver.printMasterAndAppId()

117

```

118

119

### Command Processing

120

121

Comprehensive command processing supporting SQL statements, CLI directives, and system commands.

122

123

```scala { .api }

124

// Supported command types

125

val SQL_COMMANDS = Set("SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "ALTER", "SHOW", "DESCRIBE", "EXPLAIN")

126

val CLI_COMMANDS = Set("quit", "exit", "source", "set", "reset", "add", "list", "delete")

127

val SYSTEM_COMMANDS = // Commands starting with "!"

128

129

// Command processing flow

130

def processCmd(cmd: String): Int = {

131

val trimmed = cmd.trim()

132

val tokens = trimmed.split("\\s+")

133

134

// Handle special commands

135

if (trimmed.toLowerCase.matches("quit|exit")) {

136

// Graceful shutdown

137

} else if (tokens(0).toLowerCase.equals("source")) {

138

// Execute SQL file

139

} else if (trimmed.startsWith("!")) {

140

// System command execution

141

} else {

142

// SQL statement processing with SparkSQLDriver

143

}

144

}

145

```

146

147

**Command Examples:**

148

149

```sql

150

-- SQL statements

151

SELECT * FROM employees WHERE department = 'Engineering';

152

CREATE TABLE temp_results AS SELECT * FROM analysis;

153

154

-- CLI commands

155

!ls /tmp/data/

156

source /path/to/queries.sql

157

set spark.sql.adaptive.enabled=true

158

add jar /path/to/my-udf.jar

159

list jars

160

161

-- Variable substitution

162

set hivevar:table_name=sales_2023

163

SELECT COUNT(*) FROM ${table_name};

164

```

165

166

### Interactive Shell Features

167

168

Rich interactive shell with command completion, history, and advanced editing capabilities.

169

170

```scala { .api }

171

/**

172

* Command completion support for interactive shell

173

* @return Array of Completer objects for different command types

174

*/

175

def getCommandCompleter(): Array[Completer] = {

176

// SQL keyword completion

177

val sqlCompleter = new StringsCompleter(SQLKeywordUtils.keywords.asJava)

178

179

// Function name completion

180

val functionCompleter = new StringsCompleter(

181

FunctionRegistry.builtin.listFunction().map(_.funcName).asJava

182

)

183

184

// Configuration parameter completion

185

val confCompleter = new StringsCompleter(

186

SQLConf.get.getAllDefinedConfs.map(_._1).asJava

187

)

188

189

Array(sqlCompleter, functionCompleter, confCompleter)

190

}

191

192

// History management

193

val historyFile = System.getProperty("user.home") + "/.hivehistory"

194

reader.setHistory(new FileHistory(new File(historyFile)))

195

196

// Command prompt with current database

197

def promptWithCurrentDB: String = s"spark-sql (${currentDatabase})> "

198

```

199

200

**Interactive Features:**

201

202

```bash

203

# Tab completion for SQL keywords

204

spark-sql> SEL<TAB>

205

SELECT

206

207

# Tab completion for functions

208

spark-sql> SELECT coun<TAB>

209

count( count_if(

210

211

# Tab completion for configuration

212

spark-sql> set spark.sql.adaptive.<TAB>

213

spark.sql.adaptive.enabled

214

spark.sql.adaptive.coalescePartitions.enabled

215

216

# Command history (up/down arrows)

217

spark-sql> SELECT COUNT(*) FROM orders;

218

100

219

spark-sql> <UP ARROW> # recalls previous command

220

221

# Multi-line commands

222

spark-sql> SELECT customer_id,

223

> COUNT(*) as order_count

224

> FROM orders

225

> GROUP BY customer_id;

226

```

227

228

### Signal Handling

229

230

Comprehensive signal handling for graceful interruption and shutdown.

231

232

```scala { .api }

233

/**

234

* Signal handler for Ctrl+C interruption

235

*/

236

val signalHandler = new SignalHandler() {

237

private var interruptRequested: Boolean = false

238

239

override def handle(signal: Signal): Unit = {

240

val initialRequest = !interruptRequested

241

interruptRequested = true

242

243

if (!initialRequest) {

244

// Second Ctrl+C - force exit

245

println("Exiting the JVM")

246

SparkSQLCLIDriver.exit(-1)

247

} else {

248

// First Ctrl+C - interrupt current operation

249

println("Interrupting... Be patient, this might take some time.")

250

println("Press Ctrl+C again to kill JVM")

251

HiveInterruptUtils.interrupt()

252

}

253

}

254

}

255

256

// Install signal handler

257

Signal.handle(new Signal("INT"), signalHandler)

258

```

259

260

**Signal Handling Behavior:**

261

262

```bash

263

spark-sql> SELECT COUNT(*) FROM huge_table;

264

# Long running query...

265

^C # First Ctrl+C

266

Interrupting... Be patient, this might take some time.

267

Press Ctrl+C again to kill JVM

268

269

^C # Second Ctrl+C

270

Exiting the JVM

271

```

272

273

### SQL Statement Parsing

274

275

Advanced SQL statement parsing with support for comments, multi-line statements, and proper semicolon handling.

276

277

```scala { .api }

278

/**

279

* Split input line into individual SQL statements

280

* Handles quoted strings, comments, and escaped characters

281

* @param line Input line containing one or more SQL statements

282

* @return JList of individual SQL statements

283

*/

284

def splitSemiColon(line: String): JList[String] = {

285

var insideSingleQuote = false

286

var insideDoubleQuote = false

287

var insideSimpleComment = false

288

var bracketedCommentLevel = 0

289

var escape = false

290

var beginIndex = 0

291

var isStatement = false

292

val ret = new JArrayList[String]

293

294

// Complex parsing logic for:

295

// - Quoted strings with embedded semicolons

296

// - Single-line comments (--)

297

// - Multi-line bracketed comments (/* */)

298

// - Escaped characters

299

// - Statement boundaries

300

}

301

```

302

303

**Parsing Examples:**

304

305

```sql

306

-- Multiple statements on one line

307

SELECT 1; SELECT 'hello; world'; SELECT 2;

308

309

-- Comments with semicolons

310

SELECT * FROM table1; -- This is a comment with ; semicolon

311

SELECT * FROM table2;

312

313

-- Multi-line statements

314

SELECT customer_id,

315

SUM(amount) as total

316

FROM orders

317

WHERE order_date >= '2023-01-01'

318

AND status = 'completed'

319

GROUP BY customer_id;

320

321

-- Bracketed comments

322

SELECT /* this is a

323

multi-line comment with ; semicolon */

324

COUNT(*) FROM sales;

325

```

326

327

### File Processing

328

329

Support for executing SQL files with comprehensive error handling and progress tracking.

330

331

```scala { .api }

332

/**

333

* Process SQL file with error handling

334

* @param fileName Path to SQL file to execute

335

* @return 0 on success, non-zero on error

336

*/

337

def processFile(fileName: String): Int = {

338

try {

339

val file = new File(fileName)

340

if (!file.exists()) {

341

throw new FileNotFoundException(s"File not found: $fileName")

342

}

343

344

// Process file line by line

345

Source.fromFile(file).getLines().foreach { line =>

346

if (!line.trim.startsWith("--") && line.trim.nonEmpty) {

347

val result = processLine(line, allowInterrupting = false)

348

if (result != 0) {

349

return result

350

}

351

}

352

}

353

0

354

} catch {

355

case e: FileNotFoundException =>

356

logError(s"Could not open input file for reading. (${e.getMessage})")

357

1

358

}

359

}

360

```

361

362

**File Processing Examples:**

363

364

```bash

365

# Execute SQL file

366

spark-sql -f /path/to/setup.sql

367

368

# Execute with error handling

369

spark-sql -f /path/to/queries.sql --silent

370

```

371

372

### Configuration Management

373

374

Comprehensive configuration management supporting both Spark and Hive configuration parameters.

375

376

```scala { .api }

377

// Configuration sources and precedence:

378

// 1. Command line --hiveconf options

379

// 2. Hive configuration files

380

// 3. Spark configuration

381

// 4. Default values

382

383

// Set configuration during startup

384

val hiveConf = new HiveConf()

385

sessionState.cmdProperties.entrySet().asScala.foreach { item =>

386

val key = item.getKey.toString

387

val value = item.getValue.toString

388

hiveConf.set(key, value)

389

}

390

391

// Configuration parameter handling

392

def setConfMap(conf: SQLContext, confMap: java.util.Map[String, String]): Unit = {

393

confMap.asScala.foreach { case (key, value) =>

394

try {

395

conf.setConf(key, value)

396

} catch {

397

case e: Exception =>

398

println(s"Warning: Could not set $key = $value: ${e.getMessage}")

399

}

400

}

401

}

402

```

403

404

**Configuration Examples:**

405

406

```bash

407

# Set configuration via command line

408

spark-sql --hiveconf spark.sql.adaptive.enabled=true \

409

--hiveconf hive.exec.dynamic.partition=true

410

411

# Set configuration in interactive mode

412

spark-sql> set spark.sql.shuffle.partitions=200;

413

spark-sql> set hive.exec.dynamic.partition.mode=nonstrict;

414

415

# Show current configuration

416

spark-sql> set;

417

spark-sql> set spark.sql.adaptive.enabled;

418

```

419

420

### Error Handling and Recovery

421

422

Comprehensive error handling with proper recovery and user feedback.

423

424

```scala { .api }

425

/**

426

* Handle command execution errors with proper user feedback

427

*/

428

def handleCommandError(e: Throwable, command: String): Int = {

429

e match {

430

case st: SparkThrowable =>

431

val format = SparkSQLEnv.sqlContext.conf.errorMessageFormat

432

val message = SparkThrowableHelper.getMessage(st, format)

433

System.err.println(message)

434

435

// Print stack trace for non-user errors

436

if (format == ErrorMessageFormat.PRETTY &&

437

!sessionState.getIsSilent &&

438

(!e.isInstanceOf[AnalysisException] || e.getCause != null)) {

439

e.printStackTrace(System.err)

440

}

441

442

case _ =>

443

System.err.println(s"Error executing command: ${e.getMessage}")

444

if (!sessionState.getIsSilent) {

445

e.printStackTrace(System.err)

446

}

447

}

448

1 // Return error code

449

}

450

451

// Ignore errors mode

452

val ignoreErrors = HiveConf.getBoolVar(conf, HiveConf.ConfVars.CLIIGNOREERRORS)

453

if (commandResult != 0 && !ignoreErrors) {

454

return commandResult // Stop on first error

455

}

456

```

457

458

**Error Handling Examples:**

459

460

```bash

461

# Error handling in interactive mode

462

spark-sql> SELECT * FROM non_existent_table;

463

Error in query: Table or view not found: non_existent_table

464

465

# Continue processing on errors

466

spark-sql --hiveconf hive.cli.errors.ignore=true -f queries_with_errors.sql

467

468

# Silent mode (suppress warnings)

469

spark-sql --silent -e "SELECT COUNT(*) FROM my_table"

470

```