diff --git a/pegjs/transactsql.pegjs b/pegjs/transactsql.pegjs index 3d9ee42a..f7bc2473 100644 --- a/pegjs/transactsql.pegjs +++ b/pegjs/transactsql.pegjs @@ -13,6 +13,7 @@ 'CALL': true, 'CASE': true, 'CREATE': true, + 'CROSS': true, 'CONTAINS': true, 'CURRENT_DATE': true, 'CURRENT_TIME': true, @@ -1707,7 +1708,8 @@ table_base join_op = a:(KW_LEFT / KW_RIGHT / KW_FULL) __ s:KW_OUTER? __ KW_JOIN { return [a[0].toUpperCase(), s && s[0], 'JOIN'].filter(v => v).join(' '); } - / KW_CROSS __ KW_JOIN { return 'CROSS JOIN' } + / KW_CROSS __ j:(KW_JOIN / KW_APPLY) { return `CROSS ${j[0].toUpperCase()}` } + / a:KW_OUTER __ KW_APPLY { return 'OUTER APPLY' } / a:(KW_INNER)? __ KW_JOIN { return a ? 'INNER JOIN' : 'JOIN' } table_name @@ -2798,6 +2800,7 @@ KW_FULL = "FULL"i !ident_start KW_INNER = "INNER"i !ident_start KW_CROSS = "CROSS"i !ident_start KW_JOIN = "JOIN"i !ident_start +KW_APPLY = "APPLY"i !ident_start KW_OUTER = "OUTER"i !ident_start KW_OVER = "OVER"i !ident_start KW_UNION = "UNION"i !ident_start diff --git a/test/transactsql.spec.js b/test/transactsql.spec.js index 370c0072..47e121c0 100644 --- a/test/transactsql.spec.js +++ b/test/transactsql.spec.js @@ -283,6 +283,13 @@ describe('transactsql', () => { sql = [base, 'for xml path(\'\')'].join('\n') expect(getParsedSql(sql)).to.be.equal(`${sqlfiyBase} FOR XML PATH('')`) }) + it('should support cross and outer apply', () => { + const applies = ['cross', 'outer'] + for (const apply of applies) { + const sql = `SELECT SampleParentTable.SampleColumn, SUB.SampleColumn FROM SampleParentTable ${apply} APPLY (SELECT TOP 1 SampleColumn FROM SampleChildTable) SUB` + expect(getParsedSql(sql)).to.be.equal(`SELECT [SampleParentTable].[SampleColumn], [SUB].[SampleColumn] FROM [SampleParentTable] ${apply.toUpperCase()} APPLY (SELECT TOP 1 [SampleColumn] FROM [SampleChildTable]) AS [SUB]`) + } + }) describe('if else', () => { it('should support if only statement', () => { const sql = `IF EXISTS(SELECT 1 from sys.views where name='MyView' and type='v')