Skip to content

Commit

Permalink
fix: createFunction and createFunctionLoadable
Browse files Browse the repository at this point in the history
  • Loading branch information
liuxy0551 committed Jul 31, 2024
1 parent 95a1087 commit e83449a
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 17 deletions.
30 changes: 21 additions & 9 deletions src/grammar/mysql/MySqlParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ ddlStatement
| createLogfileGroup
| createProcedure
| createFunction
| createFunctionLoadable
| createServer
| createTable
| createTablespaceInnodb
Expand Down Expand Up @@ -266,6 +267,22 @@ createProcedure
)* ')' routineOption* routineBody
;

createFunction
: KW_CREATE ownerStatement? KW_AGGREGATE? KW_FUNCTION ifNotExists? functionNameCreate '(' functionParameter? (
',' functionParameter
)* ')' KW_RETURNS dataType routineOption* (routineBody | returnStatement)
;

// https://dev.mysql.com/doc/refman/8.0/en/create-function-loadable.html
createFunctionLoadable
: KW_CREATE KW_AGGREGATE? KW_FUNCTION ifNotExists? functionNameCreate KW_RETURNS returnType=(
KW_STRING
| KW_INTEGER
| KW_REAL
| KW_DECIMAL
) KW_SONAME STRING_LITERAL
;

createRole
: KW_CREATE KW_ROLE ifNotExists? userOrRoleNames
;
Expand Down Expand Up @@ -420,6 +437,10 @@ procedureParameter
: direction=(KW_IN | KW_OUT | KW_INOUT)? paramName=uid dataType
;

functionParameter
: paramName=uid dataType
;

routineOption
: KW_COMMENT STRING_LITERAL # routineComment
| KW_LANGUAGE KW_SQL # routineLanguage
Expand Down Expand Up @@ -1984,15 +2005,6 @@ checkTableOption
| KW_CHANGED
;

createFunction
: KW_CREATE KW_AGGREGATE? KW_FUNCTION ifNotExists? functionNameCreate KW_RETURNS returnType=(
KW_STRING
| KW_INTEGER
| KW_REAL
| KW_DECIMAL
) KW_SONAME STRING_LITERAL
;

installComponent
: KW_INSTALL KW_COMPONENT component_name=uid (',' component_name=uid)* (
KW_SET variableExpr (',' variableExpr)*
Expand Down
9 changes: 9 additions & 0 deletions src/parser/mysql/mysqlEntityCollector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
CopyCreateTableContext,
CreateDatabaseContext,
CreateFunctionContext,
CreateFunctionLoadableContext,
CreateViewContext,
DatabaseNameContext,
DatabaseNameCreateContext,
Expand Down Expand Up @@ -143,4 +144,12 @@ export class MySqlEntityCollector extends EntityCollector implements MySqlParser
exitCreateFunction(ctx: CreateFunctionContext) {
this.popStmt();
}

enterCreateFunctionLoadable(ctx: CreateFunctionLoadableContext) {
this.pushStmt(ctx, StmtContextType.CREATE_FUNCTION_STMT);
}

exitCreateFunctionLoadable(ctx: CreateFunctionLoadableContext) {
this.popStmt();
}
}
54 changes: 46 additions & 8 deletions test/parser/mysql/contextCollect/entityCollector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('MySQL entity collector tests', () => {
});

test('split results', () => {
expect(splitListener.statementsContext.length).toBe(15);
expect(splitListener.statementsContext.length).toBe(16);
});

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

expect(functionEntity.entityContextType).toBe(EntityContextType.FUNCTION_CREATE);
expect(functionEntity.text).toBe('my_concat_ws');
expect(functionEntity.text).toBe('hello');
expect(functionEntity.position).toEqual({
endColumn: 43,
endIndex: 982,
endColumn: 39,
endIndex: 978,
line: 39,
startColumn: 31,
startIndex: 971,
startColumn: 34,
startIndex: 974,
});

expect(functionEntity.belongStmt.stmtContextType).toBe(
StmtContextType.CREATE_FUNCTION_STMT
);
expect(functionEntity.belongStmt.position).toEqual({
endColumn: 87,
endIndex: 1026,
endColumn: 114,
endIndex: 1053,
endLine: 39,
startColumn: 1,
startIndex: 941,
Expand All @@ -492,4 +492,42 @@ describe('MySQL entity collector tests', () => {
expect(functionEntity.columns).toBeNull();
expect(functionEntity.relatedEntities).toBeNull();
});

test('create function loadable', () => {
const functionCreateContext = splitListener.statementsContext[15];

const collectListener = new MySqlEntityCollector(commonSql);
mysql.listen(collectListener as ParseTreeListener, functionCreateContext);

const allEntities = collectListener.getEntities();

expect(allEntities.length).toBe(1);

const functionEntity = allEntities[0];

expect(functionEntity.entityContextType).toBe(EntityContextType.FUNCTION_CREATE);
expect(functionEntity.text).toBe('my_concat_ws');
expect(functionEntity.position).toEqual({
endColumn: 43,
endIndex: 1098,
line: 41,
startColumn: 31,
startIndex: 1087,
});

expect(functionEntity.belongStmt.stmtContextType).toBe(
StmtContextType.CREATE_FUNCTION_STMT
);
expect(functionEntity.belongStmt.position).toEqual({
endColumn: 87,
endIndex: 1142,
endLine: 41,
startColumn: 1,
startIndex: 1057,
startLine: 41,
});

expect(functionEntity.columns).toBeNull();
expect(functionEntity.relatedEntities).toBeNull();
});
});
2 changes: 2 additions & 0 deletions test/parser/mysql/contextCollect/fixtures/common.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,6 @@ SHOW CREATE SCHEMA IF NOT EXISTS db_name;

DROP SCHEMA IF EXISTS db_name;

CREATE DEFINER = 'user' FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN CONCAT('Hello, ',s,'!');

CREATE FUNCTION IF NOT EXISTS my_concat_ws RETURNS STRING SONAME 'udf_my_concat_ws.so';
17 changes: 17 additions & 0 deletions test/parser/mysql/syntax/fixtures/createFunction.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,20 @@ CREATE FUNCTION my_concat_ws RETURNS INTEGER SONAME 'udf_my_concat_ws.so';
CREATE FUNCTION my_concat_ws RETURNS REAL SONAME 'udf_my_concat_ws.so';
CREATE FUNCTION my_concat_ws RETURNS DECIMAL SONAME 'udf_my_concat_ws.so';
CREATE FUNCTION IF NOT EXISTS my_concat_ws RETURNS DECIMAL SONAME 'udf_my_concat_ws.so';



-- https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html

CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN CONCAT('Hello, ',s,'!');
CREATE DEFINER = 'user' FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN CONCAT('Hello, ',s,'!');
CREATE FUNCTION `uuidToBinary`(_uuid BINARY(36)) RETURNS binary(16) DETERMINISTIC SQL SECURITY INVOKER RETURN UNHEX(
CONCAT(
SUBSTR(_uuid, 15, 4),
SUBSTR(_uuid, 10, 4),
SUBSTR(_uuid, 1, 8),
SUBSTR(_uuid, 20, 4),
SUBSTR(_uuid, 25)
)
);
CREATE FUNCTION AddNumbers(num1 INT, num2 INT) RETURNS INT RETURN num1 + num2;

0 comments on commit e83449a

Please sign in to comment.