or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bridge.mdexpressions.mdfunctions.mdindex.mdoperations.mdserialization.mdtypeinfo.mdtypes.md

operations.mddocs/

0

# Expression Operations and Operators

1

2

The `ImplicitExpressionOperations` trait provides a rich set of operations for building and manipulating expressions using natural Scala syntax with operator overloading.

3

4

## Core Operations Trait

5

6

```scala { .api }

7

trait ImplicitExpressionOperations {

8

private[flink] def expr: Expression

9

10

// Field aliasing with symbols

11

def as(name: Symbol, extraNames: Symbol*): Expression

12

13

// Comparison operators

14

def >(other: Expression): Expression

15

def >=(other: Expression): Expression

16

def <(other: Expression): Expression

17

def <=(other: Expression): Expression

18

def ===(other: Expression): Expression

19

def !==(other: Expression): Expression

20

21

// Logical operators

22

def &&(other: Expression): Expression

23

def ||(other: Expression): Expression

24

def unary_!: Expression

25

26

// Arithmetic operators

27

def +(other: Expression): Expression

28

def -(other: Expression): Expression

29

def *(other: Expression): Expression

30

def /(other: Expression): Expression

31

def %(other: Expression): Expression

32

def unary_-: Expression

33

def unary_+: Expression

34

35

// Specialized operations

36

def to(other: Expression): Expression

37

def ?(ifTrue: Expression, ifFalse: Expression): Expression

38

def rows: Expression

39

}

40

```

41

42

## Field Aliasing

43

44

### Symbol-Based Aliasing

45

46

```scala { .api }

47

def as(name: Symbol, extraNames: Symbol*): Expression

48

```

49

50

Usage examples:

51

```scala

52

import org.apache.flink.table.api._

53

54

// Single alias

55

val aliased = $"price" * 1.1 as 'totalPrice

56

57

// Multiple aliases (for expressions that expand to multiple fields)

58

val multiAlias = someComplexExpression as ('field1, 'field2, 'field3)

59

```

60

61

The trait also inherits string-based aliasing from the base implementation:

62

```scala

63

// String-based aliasing (inherited)

64

val stringAlias = $"price" * 1.1 as "totalPrice"

65

```

66

67

## Comparison Operations

68

69

### Relational Operators

70

71

```scala { .api }

72

def >(other: Expression): Expression // Greater than

73

def >=(other: Expression): Expression // Greater than or equal

74

def <(other: Expression): Expression // Less than

75

def <=(other: Expression): Expression // Less than or equal

76

def ===(other: Expression): Expression // Equal (use === to avoid conflicts)

77

def !==(other: Expression): Expression // Not equal

78

```

79

80

Usage examples:

81

```scala

82

// Numeric comparisons

83

val condition1 = $"age" > lit(18)

84

val condition2 = $"salary" >= lit(50000.0)

85

val condition3 = $"score" < lit(100)

86

val condition4 = $"rating" <= lit(5.0)

87

88

// Equality comparisons

89

val isActive = $"status" === lit("ACTIVE")

90

val notDeleted = $"deleted" !== lit(true)

91

92

// String comparisons

93

val nameFilter = $"name" === lit("John")

94

95

// Date comparisons

96

val recentOrders = $"orderDate" > lit(LocalDate.now().minusDays(30))

97

```

98

99

## Logical Operations

100

101

### Boolean Operators

102

103

```scala { .api }

104

def &&(other: Expression): Expression // Logical AND

105

def ||(other: Expression): Expression // Logical OR

106

def unary_!: Expression // Logical NOT

107

```

108

109

Usage examples:

110

```scala

111

// Complex conditions

112

val adultActive = ($"age" >= lit(18)) && ($"status" === lit("ACTIVE"))

113

val eligibleUser = ($"premium" === lit(true)) || ($"trialExpiry" > currentDate())

114

val nonDeleted = !($"deleted" === lit(true))

115

116

// Chained logical operations

117

val complexFilter = ($"category" === lit("ELECTRONICS")) &&

118

(($"price" > lit(100)) || ($"discount" > lit(0.2))) &&

119

!($"outOfStock" === lit(true))

120

```

121

122

## Arithmetic Operations

123

124

### Mathematical Operators

125

126

```scala { .api }

127

def +(other: Expression): Expression // Addition

128

def -(other: Expression): Expression // Subtraction

129

def *(other: Expression): Expression // Multiplication

130

def /(other: Expression): Expression // Division

131

def %(other: Expression): Expression // Modulo

132

def unary_-: Expression // Negation

133

def unary_+: Expression // Positive (identity)

134

```

135

136

Usage examples:

137

```scala

138

// Basic arithmetic

139

val totalPrice = $"price" + $"tax"

140

val discount = $"originalPrice" - $"finalPrice"

141

val area = $"width" * $"height"

142

val average = $"sum" / $"count"

143

val remainder = $"value" % lit(10)

144

145

// Unary operations

146

val negated = -$"balance"

147

val positive = +$"amount"

148

149

// Complex calculations

150

val finalAmount = ($"price" * $"quantity") +

151

($"price" * $"quantity" * $"taxRate") -

152

$"discount"

153

154

// Mathematical expressions with literals

155

val adjustedScore = ($"score" * lit(1.1)) + lit(5.0)

156

```

157

158

## Specialized Operations

159

160

### Range Expression

161

162

```scala { .api }

163

def to(other: Expression): Expression

164

```

165

166

Creates a range expression for column selection:

167

168

```scala

169

// Select columns from 'start' to 'end'

170

val columnRange = $"col1" to $"col5" // Selects col1, col2, col3, col4, col5

171

172

// Usage in select

173

val result = table.select(columnRange)

174

```

175

176

### Ternary Conditional

177

178

```scala { .api }

179

def ?(ifTrue: Expression, ifFalse: Expression): Expression

180

```

181

182

Provides ternary conditional operator:

183

184

```scala

185

// Conditional expressions

186

val status = ($"age" >= lit(18)) ? lit("Adult") : lit("Minor")

187

val category = ($"score" > lit(80)) ? lit("High") :

188

(($"score" > lit(60)) ? lit("Medium") : lit("Low"))

189

190

// Null handling

191

val displayName = $"nickname".isNotNull ? $"nickname" : $"firstName"

192

193

// Numeric conditionals

194

val finalPrice = ($"memberType" === lit("PREMIUM")) ?

195

($"price" * lit(0.9)) : $"price"

196

```

197

198

### Row Interval

199

200

```scala { .api }

201

def rows: Expression

202

```

203

204

Creates row interval for windowing operations:

205

206

```scala

207

// Window with row-based bounds

208

val windowSpec = Over

209

.partitionBy($"userId")

210

.orderBy($"timestamp")

211

.preceding(lit(5).rows) // 5 rows preceding

212

.currentRow()

213

214

// Usage in window function

215

val result = table.select(

216

$"*",

217

$"amount".sum.over(windowSpec) as "runningSum"

218

)

219

```

220

221

## Complex Expression Examples

222

223

### Nested Conditional Logic

224

225

```scala

226

// Multi-level conditionals

227

val priorityLevel = ($"urgent" === lit(true)) ? lit("HIGH") :

228

(($"important" === lit(true)) ? lit("MEDIUM") : lit("LOW"))

229

230

// Combining with arithmetic

231

val adjustedPrice = ($"customerType" === lit("VIP")) ?

232

($"price" * lit(0.8)) :

233

(($"customerType" === lit("MEMBER")) ?

234

($"price" * lit(0.9)) : $"price")

235

```

236

237

### Complex Filtering

238

239

```scala

240

// Advanced filtering conditions

241

val eligibleCustomers = table.filter(

242

($"age" >= lit(18)) &&

243

($"creditScore" > lit(650)) &&

244

(($"income" > lit(50000)) || ($"assets" > lit(100000))) &&

245

!($"blacklisted" === lit(true))

246

)

247

```

248

249

### Mathematical Computations

250

251

```scala

252

// Complex mathematical expressions

253

val distanceFormula = (($"x2" - $"x1") * ($"x2" - $"x1")) +

254

(($"y2" - $"y1") * ($"y2" - $"y1"))

255

256

val normalizedScore = ($"rawScore" - $"minScore") /

257

($"maxScore" - $"minScore")

258

259

// Statistical calculations

260

val zScore = ($"value" - $"mean") / $"standardDeviation"

261

```

262

263

### String and Date Operations

264

265

```scala

266

// String operations (when combined with built-in functions)

267

val fullName = concat($"firstName", lit(" "), $"lastName")

268

val emailDomain = substring($"email", position($"email", lit("@")) + lit(1))

269

270

// Date arithmetic

271

val daysSinceOrder = currentDate() - $"orderDate"

272

val futureDate = $"startDate" + interval(lit(30), DAY)

273

```

274

275

## Type Safety and Compatibility

276

277

### Expression Type Preservation

278

279

Operations maintain proper type information:

280

281

```scala

282

val intResult: Expression = $"intField" + lit(5) // Type: INT

283

val doubleResult: Expression = $"price" * lit(1.1) // Type: DOUBLE

284

val stringResult: Expression = $"name" + lit(" Jr.") // Type: STRING

285

val boolResult: Expression = $"age" > lit(18) // Type: BOOLEAN

286

```

287

288

### Null Handling

289

290

All operations handle null values according to SQL semantics:

291

292

```scala

293

// Null-safe operations

294

val safeAdd = $"nullableField" + lit(10) // null + 10 = null

295

val safeCompare = $"nullableField" > lit(5) // null > 5 = null

296

val safeLogical = $"boolField" && lit(true) // null && true = null

297

```

298

299

### Automatic Type Coercion

300

301

Compatible types are automatically coerced:

302

303

```scala

304

val intDouble = $"intField" + lit(3.14) // int + double = double

305

val intLong = $"intField" + lit(100L) // int + long = long

306

val numericString = $"price" + lit(" USD") // double + string = string

307

```

308

309

## Performance Considerations

310

311

### Expression Optimization

312

313

- Expressions are optimized during query planning

314

- Constant folding applied to literal operations

315

- Common subexpression elimination

316

- Predicate pushdown for filter conditions

317

318

### Lazy Evaluation

319

320

- Operations build expression trees without immediate evaluation

321

- Actual computation occurs during query execution

322

- Allows for query optimization opportunities

323

324

### Memory Efficiency

325

326

- Expression objects are lightweight wrappers

327

- No intermediate results stored during expression building

328

- Memory usage scales with expression complexity, not data size

329

330

## Best Practices

331

332

### Readable Complex Expressions

333

334

```scala

335

// Break complex expressions into readable parts

336

val isEligibleAge = $"age" >= lit(18)

337

val hasGoodCredit = $"creditScore" > lit(650)

338

val hasIncome = $"income" > lit(30000)

339

340

val eligibleCustomer = isEligibleAge && hasGoodCredit && hasIncome

341

```

342

343

### Consistent Null Handling

344

345

```scala

346

// Explicit null checks when needed

347

val safeCalculation = $"value".isNotNull ?

348

($"value" * lit(1.1)) :

349

lit(0.0)

350

```

351

352

### Type-Aware Operations

353

354

```scala

355

// Use appropriate literal types

356

val intOp = $"intField" + lit(5) // lit(5) creates INT literal

357

val doubleOp = $"doubleField" + lit(5.0) // lit(5.0) creates DOUBLE literal

358

val stringOp = $"textField" + lit("suffix") // lit("suffix") creates STRING literal

359

```