Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 96e35f2

Browse files
authored
MySQL: support mysql types for binary expr and sum (#4254)
1 parent 7c92b0c commit 96e35f2

File tree

3 files changed

+219
-0
lines changed
  • dialects/mysql/src/main/kotlin/app/cash/sqldelight/dialects/mysql
  • sqldelight-gradle-plugin/src/test/integration-mysql/src
    • main/sqldelight/app/cash/sqldelight/mysql/integration
    • test/kotlin/app/cash/sqldelight/mysql/integration

3 files changed

+219
-0
lines changed

dialects/mysql/src/main/kotlin/app/cash/sqldelight/dialects/mysql/MySqlTypeResolver.kt

+43
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ import app.cash.sqldelight.dialects.mysql.MySqlType.SMALL_INT
1414
import app.cash.sqldelight.dialects.mysql.MySqlType.TINY_INT
1515
import app.cash.sqldelight.dialects.mysql.grammar.psi.MySqlExtensionExpr
1616
import app.cash.sqldelight.dialects.mysql.grammar.psi.MySqlTypeName
17+
import com.alecstrong.sql.psi.core.psi.SqlBinaryAddExpr
18+
import com.alecstrong.sql.psi.core.psi.SqlBinaryExpr
19+
import com.alecstrong.sql.psi.core.psi.SqlBinaryMultExpr
20+
import com.alecstrong.sql.psi.core.psi.SqlBinaryPipeExpr
1721
import com.alecstrong.sql.psi.core.psi.SqlExpr
1822
import com.alecstrong.sql.psi.core.psi.SqlFunctionExpr
1923
import com.alecstrong.sql.psi.core.psi.SqlTypeName
24+
import com.alecstrong.sql.psi.core.psi.SqlTypes
2025
import com.intellij.psi.PsiElement
26+
import com.intellij.psi.tree.TokenSet
2127
import com.intellij.psi.util.PsiTreeUtil
2228

2329
class MySqlTypeResolver(
@@ -32,6 +38,31 @@ class MySqlTypeResolver(
3238
TEXT,
3339
BLOB,
3440
)
41+
is SqlBinaryExpr -> {
42+
if (expr.childOfType(
43+
TokenSet.create(
44+
SqlTypes.EQ, SqlTypes.EQ2, SqlTypes.NEQ,
45+
SqlTypes.NEQ2, SqlTypes.AND, SqlTypes.OR, SqlTypes.GT, SqlTypes.GTE,
46+
SqlTypes.LT, SqlTypes.LTE,
47+
),
48+
) != null
49+
) {
50+
IntermediateType(PrimitiveType.BOOLEAN)
51+
} else {
52+
encapsulatingType(
53+
exprList = expr.getExprList(),
54+
nullableIfAny = (expr is SqlBinaryAddExpr || expr is SqlBinaryMultExpr || expr is SqlBinaryPipeExpr),
55+
TINY_INT,
56+
SMALL_INT,
57+
MySqlType.INTEGER,
58+
INTEGER,
59+
BIG_INT,
60+
REAL,
61+
TEXT,
62+
BLOB,
63+
)
64+
}
65+
}
3566
else -> parentResolver.resolvedType(expr)
3667
}
3768
}
@@ -93,6 +124,14 @@ class MySqlTypeResolver(
93124
BIG_INT,
94125
REAL,
95126
).asNullable()
127+
"sum" -> {
128+
val type = resolvedType(exprList.single())
129+
if (type.dialectType == REAL) {
130+
IntermediateType(REAL).asNullable()
131+
} else {
132+
IntermediateType(INTEGER).asNullable()
133+
}
134+
}
96135
"unix_timestamp" -> IntermediateType(TEXT)
97136
"to_seconds" -> IntermediateType(INTEGER)
98137
"json_arrayagg" -> IntermediateType(TEXT)
@@ -136,3 +175,7 @@ class MySqlTypeResolver(
136175
)
137176
}
138177
}
178+
179+
private fun PsiElement.childOfType(types: TokenSet): PsiElement? {
180+
return node.findChildByType(types)?.psi
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
CREATE TABLE ints (
2+
`tinyint` TINYINT,
3+
`smallint` SMALLINT,
4+
`integer` INTEGER,
5+
`bigint` BIGINT(20)
6+
);
7+
8+
insertInts:
9+
INSERT INTO ints
10+
VALUES (?, ?, ?, ?);
11+
12+
multiplyInts:
13+
SELECT `tinyint`*`tinyint`, `smallint`*`smallint`, `integer`*`integer`, `bigint`*`bigint` FROM ints;
14+
15+
multiplyWithBigInts:
16+
SELECT `tinyint`*`bigint` AS tiny, `smallint`*`bigint` AS small, `integer`*`bigint` AS `integer` FROM ints;
17+
18+
sumInts:
19+
SELECT sum(`tinyint`) AS sumTiny, sum(`smallint`) AS sumSmall, sum(`integer`) AS sumInt, sum(`bigint`) AS sumBig FROM ints;
20+
21+
minInts:
22+
SELECT min(`tinyint`) AS minTiny, min(`smallint`) AS minSmall, min(`integer`) AS minInt, min(`bigint`) AS minBig FROM ints;
23+
24+
maxInts:
25+
SELECT max(`tinyint`) AS maxTiny, max(`smallint`) AS maxSmall, max(`integer`) AS maxInt, max(`bigint`) AS maxBig FROM ints;
26+
27+
CREATE TABLE floats (
28+
`float` FLOAT
29+
);
30+
31+
insertFloats:
32+
INSERT INTO floats
33+
VALUES (?);
34+
35+
sumMinMaxFloat:
36+
SELECT sum(`float`) AS sumFloat, min(`float`) AS minFloat, max(`float`) AS maxFloat FROM floats;
37+
38+
multiplyFloatInt:
39+
SELECT `float`*`bigint` AS mul FROM floats, ints;

sqldelight-gradle-plugin/src/test/integration-mysql/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt

+137
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class MySqlTest {
2323
lateinit var dogQueries: DogQueries
2424
lateinit var datesQueries: DatesQueries
2525
lateinit var charactersQueries: CharactersQueries
26+
lateinit var numbersQueries: NumbersQueries
2627
lateinit var driver: JdbcDriver
2728

2829
@Before
@@ -41,6 +42,7 @@ class MySqlTest {
4142
dogQueries = database.dogQueries
4243
datesQueries = database.datesQueries
4344
charactersQueries = database.charactersQueries
45+
numbersQueries = database.numbersQueries
4446
}
4547

4648
@After
@@ -142,6 +144,141 @@ class MySqlTest {
142144
}
143145
}
144146

147+
@Test
148+
fun testIntsMinMaxSum() {
149+
with(
150+
numbersQueries.sumInts().executeAsOne(),
151+
) {
152+
assertThat(sumTiny).isNull()
153+
assertThat(sumSmall).isNull()
154+
assertThat(sumInt).isNull()
155+
assertThat(sumBig).isNull()
156+
}
157+
158+
with(
159+
numbersQueries.minInts().executeAsOne(),
160+
) {
161+
assertThat(minTiny).isNull()
162+
assertThat(minSmall).isNull()
163+
assertThat(minInt).isNull()
164+
assertThat(minBig).isNull()
165+
}
166+
167+
with(
168+
numbersQueries.maxInts().executeAsOne(),
169+
) {
170+
assertThat(maxTiny).isNull()
171+
assertThat(maxSmall).isNull()
172+
assertThat(maxInt).isNull()
173+
assertThat(maxBig).isNull()
174+
}
175+
176+
numbersQueries.insertInts(
177+
tinyint = 1,
178+
smallint = 1,
179+
integer = 1,
180+
bigint = 1,
181+
)
182+
numbersQueries.insertInts(
183+
tinyint = 2,
184+
smallint = 2,
185+
integer = 2,
186+
bigint = 2,
187+
)
188+
189+
with(
190+
numbersQueries.sumInts().executeAsOne(),
191+
) {
192+
assertThat(sumTiny).isInstanceOf(Long::class.javaObjectType)
193+
assertThat(sumSmall).isInstanceOf(Long::class.javaObjectType)
194+
assertThat(sumInt).isInstanceOf(Long::class.javaObjectType)
195+
assertThat(sumBig).isInstanceOf(Long::class.javaObjectType)
196+
assertThat(sumTiny).isEqualTo(3)
197+
assertThat(sumSmall).isEqualTo(3)
198+
assertThat(sumInt).isEqualTo(3)
199+
assertThat(sumBig).isEqualTo(3)
200+
}
201+
202+
with(
203+
numbersQueries.minInts().executeAsOne(),
204+
) {
205+
assertThat(minTiny).isEqualTo(1)
206+
assertThat(minSmall).isEqualTo(1)
207+
assertThat(minInt).isEqualTo(1)
208+
assertThat(minBig).isEqualTo(1)
209+
}
210+
211+
with(
212+
numbersQueries.maxInts().executeAsOne(),
213+
) {
214+
assertThat(maxTiny).isEqualTo(2)
215+
assertThat(maxSmall).isEqualTo(2)
216+
assertThat(maxInt).isEqualTo(2)
217+
assertThat(maxBig).isEqualTo(2)
218+
}
219+
}
220+
221+
@Test
222+
fun testMultiplySmallerIntsBecomeLongs() {
223+
numbersQueries.insertInts(
224+
tinyint = 1,
225+
smallint = 1,
226+
integer = 1,
227+
bigint = Long.MAX_VALUE,
228+
)
229+
230+
with(
231+
numbersQueries.multiplyWithBigInts().executeAsOne(),
232+
) {
233+
assertThat(tiny).isEqualTo(Long.MAX_VALUE)
234+
assertThat(small).isEqualTo(Long.MAX_VALUE)
235+
assertThat(integer).isEqualTo(Long.MAX_VALUE)
236+
}
237+
}
238+
239+
@Test
240+
fun testFloat() {
241+
with(
242+
numbersQueries.sumMinMaxFloat().executeAsOne(),
243+
) {
244+
assertThat(sumFloat).isNull()
245+
assertThat(minFloat).isNull()
246+
assertThat(maxFloat).isNull()
247+
}
248+
249+
numbersQueries.insertFloats(
250+
float = 1.5,
251+
)
252+
253+
with(
254+
numbersQueries.sumMinMaxFloat().executeAsOne(),
255+
) {
256+
assertThat(sumFloat).isEqualTo(1.5)
257+
assertThat(minFloat).isEqualTo(1.5)
258+
assertThat(maxFloat).isEqualTo(1.5)
259+
}
260+
}
261+
262+
@Test
263+
fun testMultiplyFloatInt() {
264+
numbersQueries.insertInts(
265+
tinyint = 3,
266+
smallint = 3,
267+
integer = 3,
268+
bigint = 3,
269+
)
270+
271+
numbersQueries.insertFloats(
272+
float = 1.5,
273+
)
274+
275+
with(
276+
numbersQueries.multiplyFloatInt().executeAsOne(),
277+
) {
278+
assertThat(mul).isEqualTo(4.5)
279+
}
280+
}
281+
145282
@Test
146283
fun transactionCrashRollsBack() {
147284
val transacter = SqlDriverTransacter(driver)

0 commit comments

Comments
 (0)