Skip to content

Commit 465bf9b

Browse files
committed
fix: createFunction and createFunctionLoadable
1 parent 79e1877 commit 465bf9b

File tree

5 files changed

+95
-16
lines changed

5 files changed

+95
-16
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 & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -487,21 +487,21 @@ describe('MySQL entity collector tests', () => {
487487
const functionEntity = allEntities[0];
488488

489489
expect(functionEntity.entityContextType).toBe(EntityContextType.FUNCTION_CREATE);
490-
expect(functionEntity.text).toBe('my_concat_ws');
490+
expect(functionEntity.text).toBe('hello');
491491
expect(functionEntity.position).toEqual({
492-
endColumn: 43,
493-
endIndex: 982,
492+
endColumn: 39,
493+
endIndex: 978,
494494
line: 39,
495-
startColumn: 31,
496-
startIndex: 971,
495+
startColumn: 34,
496+
startIndex: 974,
497497
});
498498

499499
expect(functionEntity.belongStmt.stmtContextType).toBe(
500500
StmtContextType.CREATE_FUNCTION_STMT
501501
);
502502
expect(functionEntity.belongStmt.position).toEqual({
503-
endColumn: 87,
504-
endIndex: 1026,
503+
endColumn: 114,
504+
endIndex: 1053,
505505
endLine: 39,
506506
startColumn: 1,
507507
startIndex: 941,
@@ -512,4 +512,43 @@ describe('MySQL entity collector tests', () => {
512512
expect(functionEntity.relatedEntities).toBeNull();
513513
}
514514
});
515+
516+
test('create function loadable', () => {
517+
const functionCreateContext = splitListener.statementsContext[15];
518+
519+
const collectListener = new MySqlEntityCollector(commonSql);
520+
mysql.listen(collectListener as ParseTreeListener, functionCreateContext);
521+
522+
const allEntities = collectListener.getEntities();
523+
524+
expect(allEntities.length).toBe(1);
525+
526+
const functionEntity = allEntities[0];
527+
528+
expect(functionEntity.entityContextType).toBe(EntityContextType.FUNCTION_CREATE);
529+
expect(functionEntity.text).toBe('my_concat_ws');
530+
expect(functionEntity.position).toEqual({
531+
endColumn: 43,
532+
endIndex: 1098,
533+
line: 41,
534+
startColumn: 31,
535+
startIndex: 1087,
536+
});
537+
538+
expect(functionEntity.belongStmt.stmtContextType).toBe(
539+
StmtContextType.CREATE_FUNCTION_STMT
540+
);
541+
expect(functionEntity.belongStmt.position).toEqual({
542+
endColumn: 87,
543+
endIndex: 1142,
544+
endLine: 41,
545+
startColumn: 1,
546+
startIndex: 1057,
547+
startLine: 41,
548+
});
549+
if (isFuncEntityContext(functionEntity)) {
550+
expect(functionEntity.arguments).toBeNull();
551+
expect(functionEntity.relatedEntities).toBeNull();
552+
}
553+
});
515554
});

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)