diff --git a/src/languages/mariadb/likeMariaDb.ts b/src/languages/mariadb/likeMariaDb.ts index 63c7cba1f7..3428e3d6cc 100644 --- a/src/languages/mariadb/likeMariaDb.ts +++ b/src/languages/mariadb/likeMariaDb.ts @@ -9,6 +9,10 @@ export function postProcess(tokens: Token[]) { // This is SET datatype, not SET statement return { ...token, type: TokenType.RESERVED_FUNCTION_NAME }; } + if (isToken.INTERVAL(token) && nextToken.text === '(') { + // This is INTERVAL() function, not INTERVAL expression + return { ...token, type: TokenType.RESERVED_FUNCTION_NAME }; + } const prevToken = tokens[i - 1] || EOF_TOKEN; if (isToken.VALUES(token) && prevToken.text === '=') { // This is VALUES() function, not VALUES clause diff --git a/src/languages/mysql/mysql.functions.ts b/src/languages/mysql/mysql.functions.ts index 9f402b1eab..28abb8fc40 100644 --- a/src/languages/mysql/mysql.functions.ts +++ b/src/languages/mysql/mysql.functions.ts @@ -131,7 +131,6 @@ export const functions: string[] = [ 'INTERNAL_MAX_DATA_LENGTH', 'INTERNAL_TABLE_ROWS', 'INTERNAL_UPDATE_TIME', - 'INTERVAL', 'IS', 'IS_FREE_LOCK', 'IS_IPV4', diff --git a/src/languages/singlestoredb/singlestoredb.functions.ts b/src/languages/singlestoredb/singlestoredb.functions.ts index 5f30b55007..9daad84ab2 100644 --- a/src/languages/singlestoredb/singlestoredb.functions.ts +++ b/src/languages/singlestoredb/singlestoredb.functions.ts @@ -132,7 +132,6 @@ export const functions: string[] = [ 'INITCAP', 'INSERT', 'INSTR', - 'INTERVAL', 'IS', 'IS NULL', 'JSON_AGG', diff --git a/src/languages/tidb/tidb.functions.ts b/src/languages/tidb/tidb.functions.ts index 232c04911f..37cdb36c3c 100644 --- a/src/languages/tidb/tidb.functions.ts +++ b/src/languages/tidb/tidb.functions.ts @@ -116,7 +116,6 @@ export const functions: string[] = [ 'INSERT_FUNC', 'INSTR', 'INTDIV', - 'INTERVAL', 'IS_FREE_LOCK', 'IS_IPV4', 'IS_IPV4_COMPAT', diff --git a/src/lexer/token.ts b/src/lexer/token.ts index 345a46e220..24410ab0d1 100644 --- a/src/lexer/token.ts +++ b/src/lexer/token.ts @@ -80,6 +80,7 @@ export const testToken = export const isToken = { ARRAY: testToken({ text: 'ARRAY', type: TokenType.RESERVED_DATA_TYPE }), BY: testToken({ text: 'BY', type: TokenType.RESERVED_KEYWORD }), + INTERVAL: testToken({ text: 'INTERVAL', type: TokenType.RESERVED_KEYWORD }), SET: testToken({ text: 'SET', type: TokenType.RESERVED_CLAUSE }), STRUCT: testToken({ text: 'STRUCT', type: TokenType.RESERVED_DATA_TYPE }), WINDOW: testToken({ text: 'WINDOW', type: TokenType.RESERVED_CLAUSE }), diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 1a496df175..df65a07980 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -191,4 +191,19 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { GRANT ALL ON *.* TO user2; `); }); + + // Issue #985 + it('treats INTERVAL as keyword and INTERVAL() as function', () => { + expect( + format(`select now() - interval 30 day, date_sub(d, interval 1 hour), interval(5, 1, 10);`, { + keywordCase: 'upper', + functionCase: 'lower', + }) + ).toBe(dedent` + SELECT + now() - INTERVAL 30 day, + date_sub(d, INTERVAL 1 hour), + interval(5, 1, 10); + `); + }); }