Skip to content

Commit e83449a

Browse files
committed
fix: createFunction and createFunctionLoadable
1 parent 95a1087 commit e83449a

File tree

5 files changed

+95
-17
lines changed

5 files changed

+95
-17
lines changed

src/grammar/mysql/MySqlParser.g4

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ ddlStatement
7575
| createLogfileGroup
7676
| createProcedure
7777
| createFunction
78+
| createFunctionLoadable
7879
| createServer
7980
| createTable
8081
| createTablespaceInnodb
@@ -266,6 +267,22 @@ createProcedure
266267
)* ')' routineOption* routineBody
267268
;
268269

270+
createFunction
271+
: KW_CREATE ownerStatement? KW_AGGREGATE? KW_FUNCTION ifNotExists? functionNameCreate '(' functionParameter? (
272+
',' functionParameter
273+
)* ')' KW_RETURNS dataType routineOption* (routineBody | returnStatement)
274+
;
275+
276+
// https://dev.mysql.com/doc/refman/8.0/en/create-function-loadable.html
277+
createFunctionLoadable
278+
: KW_CREATE KW_AGGREGATE? KW_FUNCTION ifNotExists? functionNameCreate KW_RETURNS returnType=(
279+
KW_STRING
280+
| KW_INTEGER
281+
| KW_REAL
282+
| KW_DECIMAL
283+
) KW_SONAME STRING_LITERAL
284+
;
285+
269286
createRole
270287
: KW_CREATE KW_ROLE ifNotExists? userOrRoleNames
271288
;
@@ -420,6 +437,10 @@ procedureParameter
420437
: direction=(KW_IN | KW_OUT | KW_INOUT)? paramName=uid dataType
421438
;
422439

440+
functionParameter
441+
: paramName=uid dataType
442+
;
443+
423444
routineOption
424445
: KW_COMMENT STRING_LITERAL # routineComment
425446
| KW_LANGUAGE KW_SQL # routineLanguage
@@ -1984,15 +2005,6 @@ checkTableOption
19842005
| KW_CHANGED
19852006
;
19862007

1987-
createFunction
1988-
: KW_CREATE KW_AGGREGATE? KW_FUNCTION ifNotExists? functionNameCreate KW_RETURNS returnType=(
1989-
KW_STRING
1990-
| KW_INTEGER
1991-
| KW_REAL
1992-
| KW_DECIMAL
1993-
) KW_SONAME STRING_LITERAL
1994-
;
1995-
19962008
installComponent
19972009
: KW_INSTALL KW_COMPONENT component_name=uid (',' component_name=uid)* (
19982010
KW_SET variableExpr (',' variableExpr)*

src/parser/mysql/mysqlEntityCollector.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
CopyCreateTableContext,
55
CreateDatabaseContext,
66
CreateFunctionContext,
7+
CreateFunctionLoadableContext,
78
CreateViewContext,
89
DatabaseNameContext,
910
DatabaseNameCreateContext,
@@ -143,4 +144,12 @@ export class MySqlEntityCollector extends EntityCollector implements MySqlParser
143144
exitCreateFunction(ctx: CreateFunctionContext) {
144145
this.popStmt();
145146
}
147+
148+
enterCreateFunctionLoadable(ctx: CreateFunctionLoadableContext) {
149+
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
150+
}
151+
152+
exitCreateFunctionLoadable(ctx: CreateFunctionLoadableContext) {
153+
this.popStmt();
154+
}
146155
}

test/parser/mysql/contextCollect/entityCollector.test.ts

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('MySQL entity collector tests', () => {
2020
});
2121

2222
test('split results', () => {
23-
expect(splitListener.statementsContext.length).toBe(15);
23+
expect(splitListener.statementsContext.length).toBe(16);
2424
});
2525

2626
test('create table by columns', () => {
@@ -468,21 +468,21 @@ describe('MySQL entity collector tests', () => {
468468
const functionEntity = allEntities[0];
469469

470470
expect(functionEntity.entityContextType).toBe(EntityContextType.FUNCTION_CREATE);
471-
expect(functionEntity.text).toBe('my_concat_ws');
471+
expect(functionEntity.text).toBe('hello');
472472
expect(functionEntity.position).toEqual({
473-
endColumn: 43,
474-
endIndex: 982,
473+
endColumn: 39,
474+
endIndex: 978,
475475
line: 39,
476-
startColumn: 31,
477-
startIndex: 971,
476+
startColumn: 34,
477+
startIndex: 974,
478478
});
479479

480480
expect(functionEntity.belongStmt.stmtContextType).toBe(
481481
StmtContextType.CREATE_FUNCTION_STMT
482482
);
483483
expect(functionEntity.belongStmt.position).toEqual({
484-
endColumn: 87,
485-
endIndex: 1026,
484+
endColumn: 114,
485+
endIndex: 1053,
486486
endLine: 39,
487487
startColumn: 1,
488488
startIndex: 941,
@@ -492,4 +492,42 @@ describe('MySQL entity collector tests', () => {
492492
expect(functionEntity.columns).toBeNull();
493493
expect(functionEntity.relatedEntities).toBeNull();
494494
});
495+
496+
test('create function loadable', () => {
497+
const functionCreateContext = splitListener.statementsContext[15];
498+
499+
const collectListener = new MySqlEntityCollector(commonSql);
500+
mysql.listen(collectListener as ParseTreeListener, functionCreateContext);
501+
502+
const allEntities = collectListener.getEntities();
503+
504+
expect(allEntities.length).toBe(1);
505+
506+
const functionEntity = allEntities[0];
507+
508+
expect(functionEntity.entityContextType).toBe(EntityContextType.FUNCTION_CREATE);
509+
expect(functionEntity.text).toBe('my_concat_ws');
510+
expect(functionEntity.position).toEqual({
511+
endColumn: 43,
512+
endIndex: 1098,
513+
line: 41,
514+
startColumn: 31,
515+
startIndex: 1087,
516+
});
517+
518+
expect(functionEntity.belongStmt.stmtContextType).toBe(
519+
StmtContextType.CREATE_FUNCTION_STMT
520+
);
521+
expect(functionEntity.belongStmt.position).toEqual({
522+
endColumn: 87,
523+
endIndex: 1142,
524+
endLine: 41,
525+
startColumn: 1,
526+
startIndex: 1057,
527+
startLine: 41,
528+
});
529+
530+
expect(functionEntity.columns).toBeNull();
531+
expect(functionEntity.relatedEntities).toBeNull();
532+
});
495533
});

test/parser/mysql/contextCollect/fixtures/common.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ SHOW CREATE SCHEMA IF NOT EXISTS db_name;
3636

3737
DROP SCHEMA IF EXISTS db_name;
3838

39+
CREATE DEFINER = 'user' FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN CONCAT('Hello, ',s,'!');
40+
3941
CREATE FUNCTION IF NOT EXISTS my_concat_ws RETURNS STRING SONAME 'udf_my_concat_ws.so';

test/parser/mysql/syntax/fixtures/createFunction.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,20 @@ CREATE FUNCTION my_concat_ws RETURNS INTEGER SONAME 'udf_my_concat_ws.so';
1111
CREATE FUNCTION my_concat_ws RETURNS REAL SONAME 'udf_my_concat_ws.so';
1212
CREATE FUNCTION my_concat_ws RETURNS DECIMAL SONAME 'udf_my_concat_ws.so';
1313
CREATE FUNCTION IF NOT EXISTS my_concat_ws RETURNS DECIMAL SONAME 'udf_my_concat_ws.so';
14+
15+
16+
17+
-- https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html
18+
19+
CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN CONCAT('Hello, ',s,'!');
20+
CREATE DEFINER = 'user' FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN CONCAT('Hello, ',s,'!');
21+
CREATE FUNCTION `uuidToBinary`(_uuid BINARY(36)) RETURNS binary(16) DETERMINISTIC SQL SECURITY INVOKER RETURN UNHEX(
22+
CONCAT(
23+
SUBSTR(_uuid, 15, 4),
24+
SUBSTR(_uuid, 10, 4),
25+
SUBSTR(_uuid, 1, 8),
26+
SUBSTR(_uuid, 20, 4),
27+
SUBSTR(_uuid, 25)
28+
)
29+
);
30+
CREATE FUNCTION AddNumbers(num1 INT, num2 INT) RETURNS INT RETURN num1 + num2;

0 commit comments

Comments
 (0)