Skip to content

Commit afbadd1

Browse files
authored
Merge PR #307: New approach to function call matching
2 parents b5d66d4 + 81416cb commit afbadd1

26 files changed

Lines changed: 400 additions & 120 deletions

src/formatter/AliasAs.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ export default class AliasAs {
9999
isToken.CAST(this.getPreviousReservedToken()) &&
100100
isToken.AS(this.lookAhead()) &&
101101
(this.lookAhead(2).type === TokenType.IDENTIFIER ||
102-
this.lookAhead(2).type === TokenType.RESERVED_KEYWORD) &&
102+
this.lookAhead(2).type === TokenType.RESERVED_KEYWORD ||
103+
this.lookAhead(2).type === TokenType.RESERVED_FUNCTION_NAME) &&
103104
this.lookAhead(3).value === ')'
104105
);
105106
}

src/formatter/ExpressionFormatter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ export default class ExpressionFormatter {
200200
case TokenType.RESERVED_LOGICAL_OPERATOR:
201201
return this.formatLogicalOperator(token);
202202
case TokenType.RESERVED_KEYWORD:
203+
case TokenType.RESERVED_FUNCTION_NAME:
203204
return this.formatKeyword(token);
204205
case TokenType.RESERVED_CASE_START:
205206
return this.formatCaseStart(token);

src/languages/bigquery.formatter.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const reservedFunctions = {
6969
],
7070
// https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions
7171
array: [
72-
'ARRAY',
72+
// 'ARRAY',
7373
'ARRAY_CONCAT',
7474
'ARRAY_LENGTH',
7575
'ARRAY_TO_STRING',
@@ -545,6 +545,9 @@ const reservedFunctions = {
545545
],
546546
other: ['BQ.JOBS.CANCEL', 'BQ.REFRESH_MATERIALIZED_VIEW'],
547547
pivot: ['PIVOT', 'UNPIVOT'],
548+
// Data types with parameters like VARCHAR(100)
549+
// https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#parameterized_data_types
550+
dataTypes: ['BYTES', 'NUMERIC', 'DECIMAL', 'BIGNUMERIC', 'BIGDECIMAL', 'STRING'],
548551
};
549552

550553
/**
@@ -837,10 +840,8 @@ export default class BigQueryFormatter extends Formatter {
837840
reservedBinaryCommands,
838841
reservedJoins,
839842
reservedDependentClauses,
840-
reservedKeywords: dedupe([
841-
...Object.values(reservedFunctions).flat(),
842-
...Object.values(reservedKeywords).flat(),
843-
]),
843+
reservedKeywords: dedupe(Object.values(reservedKeywords).flat()),
844+
reservedFunctionNames: dedupe(Object.values(reservedFunctions).flat()),
844845
openParens: ['(', '['],
845846
closeParens: [')', ']'],
846847
stringTypes: [
@@ -867,14 +868,14 @@ function postProcess(tokens: Token[]): Token[] {
867868
return detectArraySubscripts(combineParameterizedTypes(tokens));
868869
}
869870

870-
// Converts OFFSET token inside array from RESERVED_COMMAND to RESERVED_KEYWORD
871+
// Converts OFFSET token inside array from RESERVED_COMMAND to RESERVED_FUNCTION_NAME
871872
// See: https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#array_subscript_operator
872873
function detectArraySubscripts(tokens: Token[]) {
873874
let prevToken = EOF_TOKEN;
874875
return tokens.map(token => {
875876
if (token.value === 'OFFSET' && prevToken.value === '[') {
876877
prevToken = token;
877-
return { ...token, type: TokenType.RESERVED_KEYWORD };
878+
return { ...token, type: TokenType.RESERVED_FUNCTION_NAME };
878879
} else {
879880
prevToken = token;
880881
return token;

src/languages/db2.formatter.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ const reservedFunctions = {
310310
row: ['UNPACK'],
311311
// https://www.ibm.com/docs/en/db2-for-zos/12?topic=expressions-olap-specification
312312
olap: ['FIRST_VALUE', 'LAG', 'LAST_VALUE', 'LEAD', 'NTH_VALUE', 'NTILE', 'RATIO_TO_REPORT'],
313+
// Type casting
314+
cast: ['CAST'],
313315
};
314316

315317
/**
@@ -342,7 +344,7 @@ const reservedKeywords = {
342344
'BY',
343345
'CAPTURE',
344346
'CASCADED',
345-
'CAST',
347+
// 'CAST',
346348
'CCSID',
347349
'CHARACTER',
348350
'CHECK',
@@ -862,10 +864,8 @@ export default class Db2Formatter extends Formatter {
862864
reservedBinaryCommands,
863865
reservedJoins,
864866
reservedDependentClauses,
865-
reservedKeywords: dedupe([
866-
...Object.values(reservedFunctions).flat(),
867-
...Object.values(reservedKeywords).flat(),
868-
]),
867+
reservedKeywords: dedupe(Object.values(reservedKeywords).flat()),
868+
reservedFunctionNames: dedupe(Object.values(reservedFunctions).flat()),
869869
stringTypes: [{ quote: "''", prefixes: ['X', 'G', 'N', 'GX', 'UX', 'U&'] }],
870870
identTypes: [`""`],
871871
positionalParams: true,

src/languages/hive.formatter.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,24 @@ const reservedFunctions = {
190190
'VARIANCE',
191191
],
192192
table: ['EXPLODE', 'INLINE', 'JSON_TUPLE', 'PARSE_URL_TUPLE', 'POSEXPLODE', 'STACK'],
193+
// https://cwiki.apache.org/confluence/display/Hive/LanguageManual+WindowingAndAnalytics
194+
window: [
195+
'LEAD',
196+
'LAG',
197+
'FIRST_VALUE',
198+
'LAST_VALUE',
199+
'RANK',
200+
'ROW_NUMBER',
201+
'DENSE_RANK',
202+
'CUME_DIST',
203+
'PERCENT_RANK',
204+
'NTILE',
205+
],
206+
// Parameterized data types
207+
// https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=82706456
208+
// Though in reality Hive only supports parameters for DECIMAL(),
209+
// it doesn't hurt to allow others in here as well.
210+
dataTypes: ['DECIMAL', 'NUMERIC', 'VARCHAR', 'CHAR'],
193211
};
194212

195213
/**
@@ -619,10 +637,8 @@ export default class HiveFormatter extends Formatter {
619637
reservedBinaryCommands,
620638
reservedJoins,
621639
reservedDependentClauses,
622-
reservedKeywords: dedupe([
623-
...Object.values(reservedFunctions).flat(),
624-
...Object.values(reservedKeywords).flat(),
625-
]),
640+
reservedKeywords: dedupe(Object.values(reservedKeywords).flat()),
641+
reservedFunctionNames: dedupe(Object.values(reservedFunctions).flat()),
626642
openParens: ['(', '['],
627643
closeParens: [')', ']'],
628644
stringTypes: ['""', "''"],

src/languages/mariadb.formatter.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ const reservedFunctions = [
180180
'NAME_CONST',
181181
'NVL',
182182
'NVL2',
183-
'NULLIF',
184183
'OCT',
185184
'OCTET_LENGTH',
186185
'ORD',
@@ -244,6 +243,41 @@ const reservedFunctions = [
244243
'WSREP_LAST_SEEN_GTID',
245244
'WSREP_SYNC_WAIT_UPTO_GTID',
246245
'YEARWEEK',
246+
// CASE expression shorthands
247+
'COALESCE',
248+
'NULLIF',
249+
// Data types with parameters
250+
// https://mariadb.com/kb/en/data-types/
251+
'TINYINT',
252+
'SMALLINT',
253+
'MEDIUMINT',
254+
'INT',
255+
'INTEGER',
256+
'BIGINT',
257+
'DECIMAL',
258+
'DEC',
259+
'NUMERIC',
260+
'FIXED',
261+
// 'NUMBER', // ?? In oracle mode only
262+
'FLOAT',
263+
'DOUBLE',
264+
'DOUBLE PRECISION',
265+
'REAL',
266+
'BIT',
267+
'BINARY',
268+
'BLOB',
269+
'CHAR',
270+
'NATIONAL CHAR',
271+
'CHAR BYTE',
272+
'ENUM',
273+
'VARBINARY',
274+
'VARCHAR',
275+
'NATIONAL VARCHAR',
276+
// 'SET' // handled as special-case in postProcess
277+
'TIME',
278+
'DATETIME',
279+
'TIMESTAMP',
280+
'YEAR',
247281
];
248282

249283
/**
@@ -1160,7 +1194,8 @@ export default class MariaDbFormatter extends Formatter {
11601194
reservedJoins,
11611195
reservedDependentClauses,
11621196
reservedLogicalOperators: ['AND', 'OR', 'XOR'],
1163-
reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]),
1197+
reservedKeywords: dedupe(reservedKeywords),
1198+
reservedFunctionNames: dedupe(reservedFunctions),
11641199
stringTypes: ['""', { quote: "''", prefixes: ['X'] }],
11651200
identTypes: ['``'],
11661201
identChars: { first: '$', rest: '$' },
@@ -1183,7 +1218,7 @@ function postProcess(tokens: Token[]) {
11831218
const nextToken = tokens[i + 1] || EOF_TOKEN;
11841219
if (isToken.SET(token) && nextToken.value === '(') {
11851220
// This is SET datatype, not SET statement
1186-
return { ...token, type: TokenType.RESERVED_KEYWORD };
1221+
return { ...token, type: TokenType.RESERVED_FUNCTION_NAME };
11871222
}
11881223
return token;
11891224
});

src/languages/mysql.formatter.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ const reservedFunctions = [
115115
'ICU_VERSION',
116116
'IF',
117117
'IFNULL',
118-
'IN',
118+
// 'IN',
119119
'INET_ATON',
120120
'INET_NTOA',
121121
'INET6_ATON',
@@ -432,6 +432,37 @@ const reservedFunctions = [
432432
// 'XOR',
433433
'YEAR',
434434
'YEARWEEK',
435+
// Data types with parameters
436+
// https://dev.mysql.com/doc/refman/8.0/en/data-types.html
437+
'BIT',
438+
'TINYINT',
439+
'SMALLINT',
440+
'MEDIUMINT',
441+
'INT',
442+
'INTEGER',
443+
'BIGINT',
444+
'DECIMAL',
445+
'DEC',
446+
'NUMERIC',
447+
'FIXED',
448+
'FLOAT',
449+
'DOUBLE',
450+
'DOUBLE PRECISION',
451+
'REAL',
452+
'DATETIME',
453+
'TIMESTAMP',
454+
'TIME',
455+
'YEAR',
456+
'CHAR',
457+
'NATIONAL CHAR',
458+
'VARCHAR',
459+
'NATIONAL VARCHAR',
460+
'BINARY',
461+
'VARBINARY',
462+
'BLOB',
463+
'TEXT',
464+
'ENUM',
465+
// 'SET' // handled as special-case in postProcess
435466
];
436467

437468
/**
@@ -656,6 +687,7 @@ const reservedKeywords = [
656687
'INSERT_METHOD',
657688
'INSTALL',
658689
'INSTANCE',
690+
'IN', // <-- moved over from functions
659691
'INT',
660692
'INT1',
661693
'INT2',
@@ -1325,7 +1357,8 @@ export default class MySqlFormatter extends Formatter {
13251357
reservedJoins,
13261358
reservedDependentClauses,
13271359
reservedLogicalOperators: ['AND', 'OR', 'XOR'],
1328-
reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]),
1360+
reservedKeywords: dedupe(reservedKeywords),
1361+
reservedFunctionNames: dedupe(reservedFunctions),
13291362
stringTypes: ['""', { quote: "''", prefixes: ['X'] }],
13301363
identTypes: ['``'],
13311364
identChars: { first: '$', rest: '$' },
@@ -1348,7 +1381,7 @@ function postProcess(tokens: Token[]) {
13481381
const nextToken = tokens[i + 1] || EOF_TOKEN;
13491382
if (isToken.SET(token) && nextToken.value === '(') {
13501383
// This is SET datatype, not SET statement
1351-
return { ...token, type: TokenType.RESERVED_KEYWORD };
1384+
return { ...token, type: TokenType.RESERVED_FUNCTION_NAME };
13521385
}
13531386
return token;
13541387
});

src/languages/n1ql.formatter.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ const reservedFunctions = [
234234
'VAR_SAMP',
235235
'WEEKDAY_MILLIS',
236236
'WEEKDAY_STR',
237+
// type casting
238+
// not implemented in N1QL, but added here now for the sake of tests
239+
// https://docs.couchbase.com/server/current/analytics/3_query.html#Vs_SQL-92
240+
'CAST',
237241
];
238242

239243
/**
@@ -518,7 +522,8 @@ export default class N1qlFormatter extends Formatter {
518522
reservedJoins,
519523
reservedDependentClauses,
520524
reservedLogicalOperators: ['AND', 'OR', 'XOR'],
521-
reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]),
525+
reservedKeywords: dedupe(reservedKeywords),
526+
reservedFunctionNames: dedupe(reservedFunctions),
522527
// NOTE: single quotes are actually not supported in N1QL,
523528
// but we support them anyway as all other SQL dialects do,
524529
// which simplifies writing tests that are shared between all dialects.

src/languages/plsql.formatter.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,36 @@ const reservedFunctions = {
234234
window: ['FIRST_VALUE', 'LAG', 'LAST_VALUE', 'LEAD', 'NTILE', 'RATIO_TO_REPORT', 'ROW_NUMBER'],
235235
objectReference: ['DEREF', 'MAKE_REF', 'REF', 'REFTOHEX', 'VALUE'],
236236
model: ['CV', 'ITERATION_NUMBER', 'PRESENTNNV', 'PRESENTV', 'PREVIOUS'],
237+
// Parameterized data types
238+
// https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Data-Types.html
239+
dataTypes: [
240+
// Oracle builtin data types
241+
'VARCHAR2',
242+
'NVARCHAR2',
243+
'NUMBER',
244+
'FLOAT',
245+
'TIMESTAMP',
246+
'INTERVAL YEAR',
247+
'INTERVAL DAY',
248+
'RAW',
249+
'UROWID',
250+
'NCHAR',
251+
// ANSI Data Types
252+
'CHARACTER',
253+
'CHAR',
254+
'CHARACTER VARYING',
255+
'CHAR VARYING',
256+
'NATIONAL CHARACTER',
257+
'NATIONAL CHAR',
258+
'NATIONAL CHARACTER VARYING',
259+
'NATIONAL CHAR VARYING',
260+
'NCHAR VARYING',
261+
'NUMERIC',
262+
'DECIMAL',
263+
'FLOAT',
264+
// SQL/DS and DB2 Data Types
265+
'VARCHAR',
266+
],
237267
};
238268

239269
/**
@@ -691,7 +721,8 @@ export default class PlSqlFormatter extends Formatter {
691721
reservedJoins,
692722
reservedDependentClauses,
693723
reservedLogicalOperators: ['AND', 'OR', 'XOR'],
694-
reservedKeywords: dedupe([...reservedKeywords, ...Object.values(reservedFunctions).flat()]),
724+
reservedKeywords: dedupe(reservedKeywords),
725+
reservedFunctionNames: dedupe(Object.values(reservedFunctions).flat()),
695726
// TODO: support custom-delimited strings: Q'{..}' q'<..>' etc
696727
stringTypes: [{ quote: "''", prefixes: ['N'] }],
697728
identTypes: [`""`],

0 commit comments

Comments
 (0)