Skip to content

Commit fea1ad1

Browse files
authored
fix: mysql case when (#317)
1 parent 5d97aea commit fea1ad1

File tree

7 files changed

+103
-39
lines changed

7 files changed

+103
-39
lines changed

src/grammar/mysql/MySqlParser.g4

+1-1
Original file line numberDiff line numberDiff line change
@@ -2779,8 +2779,8 @@ specificFunction
27792779
| KW_CONVERT '(' expression KW_USING charsetName ')' # dataTypeFunctionCall
27802780
| KW_CAST '(' expression KW_AS convertedDataType ')' # dataTypeFunctionCall
27812781
| KW_VALUES '(' columnName ')' # valuesFunctionCall
2782-
| KW_CASE expression caseFuncAlternative+ (KW_ELSE elseArg=functionArg)? KW_END # caseExpressionFunctionCall
27832782
| KW_CASE caseFuncAlternative+ (KW_ELSE elseArg=functionArg)? KW_END # caseFunctionCall
2783+
| KW_CASE expression caseFuncAlternative+ (KW_ELSE elseArg=functionArg)? KW_END # caseExpressionFunctionCall
27842784
| KW_CHAR '(' functionArgs (KW_USING charsetName)? ')' # charFunctionCall
27852785
| KW_POSITION '(' (positionString=stringLiteral | positionExpression=expression) KW_IN (
27862786
inString=stringLiteral

src/lib/mysql/MySqlParser.interp

+1-1
Large diffs are not rendered by default.

src/lib/mysql/MySqlParser.ts

+23-23
Original file line numberDiff line numberDiff line change
@@ -43810,49 +43810,49 @@ export class MySqlParser extends SQLParserBase {
4381043810
}
4381143811
break;
4381243812
case 7:
43813-
localContext = new CaseExpressionFunctionCallContext(localContext);
43813+
localContext = new CaseFunctionCallContext(localContext);
4381443814
this.enterOuterAlt(localContext, 7);
4381543815
{
4381643816
this.state = 7424;
4381743817
this.match(MySqlParser.KW_CASE);
43818-
this.state = 7425;
43819-
this.expression(0);
43820-
this.state = 7427;
43818+
this.state = 7426;
4382143819
this.errorHandler.sync(this);
4382243820
_la = this.tokenStream.LA(1);
4382343821
do {
4382443822
{
4382543823
{
43826-
this.state = 7426;
43824+
this.state = 7425;
4382743825
this.caseFuncAlternative();
4382843826
}
4382943827
}
43830-
this.state = 7429;
43828+
this.state = 7428;
4383143829
this.errorHandler.sync(this);
4383243830
_la = this.tokenStream.LA(1);
4383343831
} while (_la === 191);
43834-
this.state = 7433;
43832+
this.state = 7432;
4383543833
this.errorHandler.sync(this);
4383643834
_la = this.tokenStream.LA(1);
4383743835
if (_la === 53) {
4383843836
{
43839-
this.state = 7431;
43837+
this.state = 7430;
4384043838
this.match(MySqlParser.KW_ELSE);
43841-
this.state = 7432;
43842-
(localContext as CaseExpressionFunctionCallContext)._elseArg = this.functionArg();
43839+
this.state = 7431;
43840+
(localContext as CaseFunctionCallContext)._elseArg = this.functionArg();
4384343841
}
4384443842
}
4384543843

43846-
this.state = 7435;
43844+
this.state = 7434;
4384743845
this.match(MySqlParser.KW_END);
4384843846
}
4384943847
break;
4385043848
case 8:
43851-
localContext = new CaseFunctionCallContext(localContext);
43849+
localContext = new CaseExpressionFunctionCallContext(localContext);
4385243850
this.enterOuterAlt(localContext, 8);
4385343851
{
43854-
this.state = 7437;
43852+
this.state = 7436;
4385543853
this.match(MySqlParser.KW_CASE);
43854+
this.state = 7437;
43855+
this.expression(0);
4385643856
this.state = 7439;
4385743857
this.errorHandler.sync(this);
4385843858
_la = this.tokenStream.LA(1);
@@ -43875,7 +43875,7 @@ export class MySqlParser extends SQLParserBase {
4387543875
this.state = 7443;
4387643876
this.match(MySqlParser.KW_ELSE);
4387743877
this.state = 7444;
43878-
(localContext as CaseFunctionCallContext)._elseArg = this.functionArg();
43878+
(localContext as CaseExpressionFunctionCallContext)._elseArg = this.functionArg();
4387943879
}
4388043880
}
4388143881

@@ -48262,8 +48262,8 @@ export class MySqlParser extends SQLParserBase {
4826248262
7388,8,380,1,380,3,380,7391,8,380,1,381,1,381,1,381,3,381,7396,8,
4826348263
381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,
4826448264
1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,
48265-
1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,4,381,7428,
48266-
8,381,11,381,12,381,7429,1,381,1,381,3,381,7434,8,381,1,381,1,381,
48265+
1,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,4,381,7427,8,381,
48266+
11,381,12,381,7428,1,381,1,381,3,381,7433,8,381,1,381,1,381,1,381,
4826748267
1,381,1,381,4,381,7440,8,381,11,381,12,381,7441,1,381,1,381,3,381,
4826848268
7446,8,381,1,381,1,381,1,381,1,381,1,381,1,381,1,381,3,381,7455,
4826948269
8,381,1,381,1,381,1,381,1,381,1,381,1,381,3,381,7463,8,381,1,381,
@@ -50909,11 +50909,11 @@ export class MySqlParser extends SQLParserBase {
5090950909
7414,5,866,0,0,7414,7415,3,800,400,0,7415,7416,5,13,0,0,7416,7417,
5091050910
3,726,363,0,7417,7418,5,867,0,0,7418,7572,1,0,0,0,7419,7420,5,189,
5091150911
0,0,7420,7421,5,866,0,0,7421,7422,3,658,329,0,7422,7423,5,867,0,
50912-
0,7423,7572,1,0,0,0,7424,7425,5,23,0,0,7425,7427,3,800,400,0,7426,
50913-
7428,3,764,382,0,7427,7426,1,0,0,0,7428,7429,1,0,0,0,7429,7427,1,
50914-
0,0,0,7429,7430,1,0,0,0,7430,7433,1,0,0,0,7431,7432,5,53,0,0,7432,
50915-
7434,3,798,399,0,7433,7431,1,0,0,0,7433,7434,1,0,0,0,7434,7435,1,
50916-
0,0,0,7435,7436,5,378,0,0,7436,7572,1,0,0,0,7437,7439,5,23,0,0,7438,
50912+
0,7423,7572,1,0,0,0,7424,7426,5,23,0,0,7425,7427,3,764,382,0,7426,
50913+
7425,1,0,0,0,7427,7428,1,0,0,0,7428,7426,1,0,0,0,7428,7429,1,0,0,
50914+
0,7429,7432,1,0,0,0,7430,7431,5,53,0,0,7431,7433,3,798,399,0,7432,
50915+
7430,1,0,0,0,7432,7433,1,0,0,0,7433,7434,1,0,0,0,7434,7435,5,378,
50916+
0,0,7435,7572,1,0,0,0,7436,7437,5,23,0,0,7437,7439,3,800,400,0,7438,
5091750917
7440,3,764,382,0,7439,7438,1,0,0,0,7440,7441,1,0,0,0,7441,7439,1,
5091850918
0,0,0,7441,7442,1,0,0,0,7442,7445,1,0,0,0,7443,7444,5,53,0,0,7444,
5091950919
7446,3,798,399,0,7445,7443,1,0,0,0,7445,7446,1,0,0,0,7446,7447,1,
@@ -50961,7 +50961,7 @@ export class MySqlParser extends SQLParserBase {
5096150961
7568,3,288,144,0,7567,7566,1,0,0,0,7567,7568,1,0,0,0,7568,7569,1,
5096250962
0,0,0,7569,7570,5,867,0,0,7570,7572,1,0,0,0,7571,7392,1,0,0,0,7571,
5096350963
7397,1,0,0,0,7571,7398,1,0,0,0,7571,7405,1,0,0,0,7571,7412,1,0,0,
50964-
0,7571,7419,1,0,0,0,7571,7424,1,0,0,0,7571,7437,1,0,0,0,7571,7449,
50964+
0,7571,7419,1,0,0,0,7571,7424,1,0,0,0,7571,7436,1,0,0,0,7571,7449,
5096550965
1,0,0,0,7571,7458,1,0,0,0,7571,7471,1,0,0,0,7571,7491,1,0,0,0,7571,
5096650966
7505,1,0,0,0,7571,7518,1,0,0,0,7571,7537,1,0,0,0,7571,7547,1,0,0,
5096750967
0,7571,7554,1,0,0,0,7572,763,1,0,0,0,7573,7574,5,191,0,0,7574,7575,
@@ -51211,7 +51211,7 @@ export class MySqlParser extends SQLParserBase {
5121151211
7095,7098,7103,7106,7110,7115,7120,7125,7130,7133,7138,7143,7148,
5121251212
7154,7159,7164,7169,7173,7176,7181,7185,7189,7197,7204,7208,7213,
5121351213
7218,7222,7224,7227,7243,7253,7263,7272,7281,7288,7295,7303,7311,
51214-
7323,7330,7340,7345,7348,7353,7356,7378,7387,7390,7395,7429,7433,
51214+
7323,7330,7340,7345,7348,7353,7356,7378,7387,7390,7395,7428,7432,
5121551215
7441,7445,7454,7462,7467,7475,7480,7485,7487,7496,7501,7509,7514,
5121651216
7522,7530,7533,7543,7561,7564,7567,7571,7584,7592,7596,7601,7606,
5121751217
7612,7617,7621,7626,7631,7636,7646,7649,7653,7657,7664,7668,7697,

src/lib/mysql/MySqlParserListener.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -605,8 +605,8 @@ import { SimpleFunctionCallContext } from "./MySqlParser.js";
605605
import { CurrentUserContext } from "./MySqlParser.js";
606606
import { DataTypeFunctionCallContext } from "./MySqlParser.js";
607607
import { ValuesFunctionCallContext } from "./MySqlParser.js";
608-
import { CaseExpressionFunctionCallContext } from "./MySqlParser.js";
609608
import { CaseFunctionCallContext } from "./MySqlParser.js";
609+
import { CaseExpressionFunctionCallContext } from "./MySqlParser.js";
610610
import { CharFunctionCallContext } from "./MySqlParser.js";
611611
import { PositionFunctionCallContext } from "./MySqlParser.js";
612612
import { SubstrFunctionCallContext } from "./MySqlParser.js";
@@ -7159,29 +7159,29 @@ export class MySqlParserListener implements ParseTreeListener {
71597159
*/
71607160
exitValuesFunctionCall?: (ctx: ValuesFunctionCallContext) => void;
71617161
/**
7162-
* Enter a parse tree produced by the `caseExpressionFunctionCall`
7162+
* Enter a parse tree produced by the `caseFunctionCall`
71637163
* labeled alternative in `MySqlParser.specificFunction`.
71647164
* @param ctx the parse tree
71657165
*/
7166-
enterCaseExpressionFunctionCall?: (ctx: CaseExpressionFunctionCallContext) => void;
7166+
enterCaseFunctionCall?: (ctx: CaseFunctionCallContext) => void;
71677167
/**
7168-
* Exit a parse tree produced by the `caseExpressionFunctionCall`
7168+
* Exit a parse tree produced by the `caseFunctionCall`
71697169
* labeled alternative in `MySqlParser.specificFunction`.
71707170
* @param ctx the parse tree
71717171
*/
7172-
exitCaseExpressionFunctionCall?: (ctx: CaseExpressionFunctionCallContext) => void;
7172+
exitCaseFunctionCall?: (ctx: CaseFunctionCallContext) => void;
71737173
/**
7174-
* Enter a parse tree produced by the `caseFunctionCall`
7174+
* Enter a parse tree produced by the `caseExpressionFunctionCall`
71757175
* labeled alternative in `MySqlParser.specificFunction`.
71767176
* @param ctx the parse tree
71777177
*/
7178-
enterCaseFunctionCall?: (ctx: CaseFunctionCallContext) => void;
7178+
enterCaseExpressionFunctionCall?: (ctx: CaseExpressionFunctionCallContext) => void;
71797179
/**
7180-
* Exit a parse tree produced by the `caseFunctionCall`
7180+
* Exit a parse tree produced by the `caseExpressionFunctionCall`
71817181
* labeled alternative in `MySqlParser.specificFunction`.
71827182
* @param ctx the parse tree
71837183
*/
7184-
exitCaseFunctionCall?: (ctx: CaseFunctionCallContext) => void;
7184+
exitCaseExpressionFunctionCall?: (ctx: CaseExpressionFunctionCallContext) => void;
71857185
/**
71867186
* Enter a parse tree produced by the `charFunctionCall`
71877187
* labeled alternative in `MySqlParser.specificFunction`.

src/lib/mysql/MySqlParserVisitor.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -605,8 +605,8 @@ import { SimpleFunctionCallContext } from "./MySqlParser.js";
605605
import { CurrentUserContext } from "./MySqlParser.js";
606606
import { DataTypeFunctionCallContext } from "./MySqlParser.js";
607607
import { ValuesFunctionCallContext } from "./MySqlParser.js";
608-
import { CaseExpressionFunctionCallContext } from "./MySqlParser.js";
609608
import { CaseFunctionCallContext } from "./MySqlParser.js";
609+
import { CaseExpressionFunctionCallContext } from "./MySqlParser.js";
610610
import { CharFunctionCallContext } from "./MySqlParser.js";
611611
import { PositionFunctionCallContext } from "./MySqlParser.js";
612612
import { SubstrFunctionCallContext } from "./MySqlParser.js";
@@ -4522,19 +4522,19 @@ export class MySqlParserVisitor<Result> extends AbstractParseTreeVisitor<Result>
45224522
*/
45234523
visitValuesFunctionCall?: (ctx: ValuesFunctionCallContext) => Result;
45244524
/**
4525-
* Visit a parse tree produced by the `caseExpressionFunctionCall`
4525+
* Visit a parse tree produced by the `caseFunctionCall`
45264526
* labeled alternative in `MySqlParser.specificFunction`.
45274527
* @param ctx the parse tree
45284528
* @return the visitor result
45294529
*/
4530-
visitCaseExpressionFunctionCall?: (ctx: CaseExpressionFunctionCallContext) => Result;
4530+
visitCaseFunctionCall?: (ctx: CaseFunctionCallContext) => Result;
45314531
/**
4532-
* Visit a parse tree produced by the `caseFunctionCall`
4532+
* Visit a parse tree produced by the `caseExpressionFunctionCall`
45334533
* labeled alternative in `MySqlParser.specificFunction`.
45344534
* @param ctx the parse tree
45354535
* @return the visitor result
45364536
*/
4537-
visitCaseFunctionCall?: (ctx: CaseFunctionCallContext) => Result;
4537+
visitCaseExpressionFunctionCall?: (ctx: CaseExpressionFunctionCallContext) => Result;
45384538
/**
45394539
* Visit a parse tree produced by the `charFunctionCall`
45404540
* labeled alternative in `MySqlParser.specificFunction`.

test/parser/mysql/syntax/dml.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const mysql = new MySQL();
55

66
const features = {
77
call: readSQL(__dirname, 'call.sql'),
8+
case: readSQL(__dirname, 'case.sql'),
89
delete: readSQL(__dirname, 'delete.sql'),
910
do: readSQL(__dirname, 'do.sql'),
1011
handler: readSQL(__dirname, 'handler.sql'),
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
-- https://dev.mysql.com/doc/refman/5.7/en/case.html
2+
3+
4+
/* CASE case_value
5+
WHEN when_value THEN statement_list
6+
[WHEN when_value THEN statement_list] ...
7+
[ELSE statement_list]
8+
END CASE
9+
10+
or
11+
12+
CASE
13+
WHEN search_condition THEN statement_list
14+
[WHEN search_condition THEN statement_list] ...
15+
[ELSE statement_list]
16+
END CASE */
17+
18+
19+
SELECT
20+
id,
21+
CASE
22+
WHEN age = 18 THEN '成年'
23+
WHEN age = 60 THEN '老年'
24+
ELSE '未知'
25+
END AS name
26+
FROM people;
27+
28+
SELECT
29+
id,
30+
name,
31+
score,
32+
CASE
33+
WHEN score >= 90 THEN 'A'
34+
WHEN score >= 80 THEN 'B'
35+
WHEN score >= 70 THEN 'C'
36+
WHEN score >= 60 THEN 'D'
37+
ELSE 'F'
38+
END AS grade
39+
FROM students;
40+
41+
SELECT
42+
id,
43+
name,
44+
salary,
45+
CASE salary
46+
WHEN 1000 THEN 'Low'
47+
WHEN 2000 THEN 'Medium'
48+
WHEN 3000 THEN 'High'
49+
ELSE 'Unknown'
50+
END AS salary_grade
51+
FROM employees;
52+
53+
SELECT
54+
id,
55+
name,
56+
salary,
57+
CASE
58+
WHEN salary < 1000 THEN 'Low'
59+
WHEN salary >= 1000 AND salary < 3000 THEN 'Medium'
60+
WHEN salary >= 3000 THEN 'High'
61+
ELSE 'Unknown'
62+
END AS salary_grade
63+
FROM employees;

0 commit comments

Comments
 (0)