Skip to content

Commit f8bfd19

Browse files
committed
Add support for window functions
1 parent 62dbe75 commit f8bfd19

File tree

7 files changed

+371
-1
lines changed

7 files changed

+371
-1
lines changed

src/Tokenizer.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ final class Tokenizer
7070
'CONVERT',
7171
'CREATE',
7272
'CROSS',
73+
'CURRENT ROW',
7374
'CURRENT_TIMESTAMP',
7475
'DATABASE',
7576
'DATABASES',
@@ -108,19 +109,22 @@ final class Tokenizer
108109
'FAST',
109110
'FIELDS',
110111
'FILE',
112+
'FILTER',
111113
'FIRST',
112114
'FIXED',
113115
'FLUSH',
114116
'FOR',
115117
'FORCE',
118+
'FOLLOWING',
116119
'FOREIGN',
117120
'FULL',
118121
'FULLTEXT',
119122
'FUNCTION',
120123
'GLOBAL',
121124
'GRANT',
122125
'GRANTS',
123-
'GROUP_CONCAT',
126+
'GROUP',
127+
'GROUPS',
124128
'HEAP',
125129
'HIGH_PRIORITY',
126130
'HOSTS',
@@ -180,6 +184,7 @@ final class Tokenizer
180184
'MYISAM',
181185
'NAMES',
182186
'NATURAL',
187+
'NO OTHERS',
183188
'NOT',
184189
'NOW()',
185190
'NULL',
@@ -192,12 +197,14 @@ final class Tokenizer
192197
'ON UPDATE',
193198
'ON DELETE',
194199
'OUTFILE',
200+
'OVER',
195201
'PACK_KEYS',
196202
'PAGE',
197203
'PARTIAL',
198204
'PARTITION',
199205
'PARTITIONS',
200206
'PASSWORD',
207+
'PRECEDING',
201208
'PRIMARY',
202209
'PRIVILEGES',
203210
'PROCEDURE',
@@ -278,13 +285,15 @@ final class Tokenizer
278285
'TEMPORARY',
279286
'TERMINATED',
280287
'THEN',
288+
'TIES',
281289
'TO',
282290
'TRAILING',
283291
'TRANSACTIONAL',
284292
'TRUE',
285293
'TRUNCATE',
286294
'TYPE',
287295
'TYPES',
296+
'UNBOUNDED',
288297
'UNCOMMITTED',
289298
'UNIQUE',
290299
'UNLOCK',
@@ -329,6 +338,11 @@ final class Tokenizer
329338
'UNION',
330339
'EXCEPT',
331340
'INTERSECT',
341+
'PARTITION BY',
342+
'ROWS',
343+
'RANGE',
344+
'GROUPS',
345+
'WINDOW',
332346
];
333347

334348
/** @var string[] */
@@ -343,6 +357,7 @@ final class Tokenizer
343357
'XOR',
344358
'OR',
345359
'AND',
360+
'EXCLUDE',
346361
];
347362

348363
/** @var string[] */
@@ -353,6 +368,7 @@ final class Tokenizer
353368
'ADDTIME',
354369
'AES_DECRYPT',
355370
'AES_ENCRYPT',
371+
'APPROX_COUNT_DISTINCT',
356372
'AREA',
357373
'ASBINARY',
358374
'ASCII',
@@ -382,6 +398,7 @@ final class Tokenizer
382398
'CHARACTER_LENGTH',
383399
'CHARSET',
384400
'CHAR_LENGTH',
401+
'CHECKSUM_AGG',
385402
'COALESCE',
386403
'COERCIBILITY',
387404
'COLLATION',
@@ -397,8 +414,10 @@ final class Tokenizer
397414
'COS',
398415
'COT',
399416
'COUNT',
417+
'COUNT_BIG',
400418
'CRC32',
401419
'CROSSES',
420+
'CUME_DIST',
402421
'CURDATE',
403422
'CURRENT_DATE',
404423
'CURRENT_TIME',
@@ -420,6 +439,7 @@ final class Tokenizer
420439
'DECODE',
421440
'DEFAULT',
422441
'DEGREES',
442+
'DENSE_RANK',
423443
'DES_DECRYPT',
424444
'DES_ENCRYPT',
425445
'DIFFERENCE',
@@ -439,6 +459,7 @@ final class Tokenizer
439459
'EXTRACTVALUE',
440460
'FIELD',
441461
'FIND_IN_SET',
462+
'FIRST_VALUE',
442463
'FLOOR',
443464
'FORMAT',
444465
'FOUND_ROWS',
@@ -459,6 +480,8 @@ final class Tokenizer
459480
'GET_LOCK',
460481
'GLENGTH',
461482
'GREATEST',
483+
'GROUPING',
484+
'GROUPING_ID',
462485
'GROUP_CONCAT',
463486
'GROUP_UNIQUE_USERS',
464487
'HEX',
@@ -480,9 +503,12 @@ final class Tokenizer
480503
'ISSIMPLE',
481504
'IS_FREE_LOCK',
482505
'IS_USED_LOCK',
506+
'LAG',
483507
'LAST_DAY',
484508
'LAST_INSERT_ID',
509+
'LAST_VALUE',
485510
'LCASE',
511+
'LEAD',
486512
'LEAST',
487513
'LEFT',
488514
'LENGTH',
@@ -491,6 +517,7 @@ final class Tokenizer
491517
'LINESTRING',
492518
'LINESTRINGFROMTEXT',
493519
'LINESTRINGFROMWKB',
520+
'LISTAGG',
494521
'LN',
495522
'LOAD_FILE',
496523
'LOCALTIME',
@@ -538,6 +565,8 @@ final class Tokenizer
538565
'MULTIPOLYGONFROMTEXT',
539566
'MULTIPOLYGONFROMWKB',
540567
'NAME_CONST',
568+
'NTH_VALUE',
569+
'NTILE',
541570
'NULLIF',
542571
'NUMGEOMETRIES',
543572
'NUMINTERIORRINGS',
@@ -548,6 +577,9 @@ final class Tokenizer
548577
'ORD',
549578
'OVERLAPS',
550579
'PASSWORD',
580+
'PERCENT_RANK',
581+
'PERCENTILE_CONT',
582+
'PERCENTILE_DISC',
551583
'PERIOD_ADD',
552584
'PERIOD_DIFF',
553585
'PI',
@@ -568,6 +600,7 @@ final class Tokenizer
568600
'QUOTE',
569601
'RADIANS',
570602
'RAND',
603+
'RANK',
571604
'RELATED',
572605
'RELEASE_LOCK',
573606
'REPEAT',
@@ -576,6 +609,7 @@ final class Tokenizer
576609
'RIGHT',
577610
'ROUND',
578611
'ROW_COUNT',
612+
'ROW_NUMBER',
579613
'RPAD',
580614
'RTRIM',
581615
'SCHEMA',
@@ -593,9 +627,12 @@ final class Tokenizer
593627
'SRID',
594628
'STARTPOINT',
595629
'STD',
630+
'STDEV',
631+
'STDEVP',
596632
'STDDEV',
597633
'STDDEV_POP',
598634
'STDDEV_SAMP',
635+
'STRING_AGG',
599636
'STRCMP',
600637
'STR_TO_DATE',
601638
'SUBDATE',
@@ -632,7 +669,9 @@ final class Tokenizer
632669
'UTC_TIME',
633670
'UTC_TIMESTAMP',
634671
'UUID',
672+
'VAR',
635673
'VARIANCE',
674+
'VARP',
636675
'VAR_POP',
637676
'VAR_SAMP',
638677
'VERSION',

tests/clihighlight.html

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,3 +876,102 @@
876876
JOIN cte2
877877
WHERE
878878
cte1.a = cte2.c;
879+
---
880+
SELECT
881+
a,
882+
GROUP_CONCAT(b, '.') OVER (
883+
ORDER BY
884+
c
885+
GROUPS
886+
BETWEEN UNBOUNDED PRECEDING
887+
AND CURRENT ROW
888+
EXCLUDE NO OTHERS
889+
) AS no_others,
890+
GROUP_CONCAT(b, '.') OVER (
891+
ORDER BY
892+
c
893+
GROUPS
894+
BETWEEN UNBOUNDED PRECEDING
895+
AND CURRENT ROW
896+
EXCLUDE CURRENT ROW
897+
) AS current_row,
898+
GROUP_CONCAT(b, '.') OVER (
899+
ORDER BY
900+
c
901+
GROUPS
902+
BETWEEN UNBOUNDED PRECEDING
903+
AND CURRENT ROW
904+
EXCLUDE GROUP
905+
) AS grp,
906+
GROUP_CONCAT(b, '.') OVER (
907+
ORDER BY
908+
c
909+
GROUPS
910+
BETWEEN UNBOUNDED PRECEDING
911+
AND CURRENT ROW
912+
EXCLUDE TIES
913+
) AS tie,
914+
GROUP_CONCAT(b, '.') FILTER (
915+
WHERE
916+
c != 'two'
917+
) OVER (
918+
ORDER BY
919+
a
920+
) AS filtered,
921+
CONVERT(
922+
VARCHAR(20),
923+
AVG(SalesYTD) OVER (
924+
PARTITION BY
925+
TerritoryID
926+
ORDER BY
927+
DATEPART(yy, ModifiedDate)
928+
),
929+
1
930+
) AS MovingAvg,
931+
AVG(starting_salary) OVER w2 AVG,
932+
MIN(starting_salary) OVER w2 MIN_STARTING_SALARY,
933+
MAX(starting_salary) OVER (
934+
w1
935+
ORDER BY
936+
hire_date
937+
),
938+
LISTAGG(arg, ',') OVER (
939+
PARTITION BY
940+
part
941+
ORDER BY
942+
ord
943+
ROWS
944+
BETWEEN 1 PRECEDING
945+
AND 1 FOLLOWING
946+
) AS LISTAGG_ROWS,
947+
LISTAGG(arg, ',') OVER (
948+
PARTITION BY
949+
part
950+
ORDER BY
951+
ord
952+
RANGE
953+
BETWEEN 1 PRECEDING
954+
AND 1 FOLLOWING
955+
) AS LISTAGG_RANGE,
956+
MIN(Revenue) OVER (
957+
PARTITION BY
958+
DepartmentID
959+
ORDER BY
960+
RevenueYear
961+
ROWS
962+
BETWEEN CURRENT ROW
963+
AND UNBOUNDED FOLLOWING
964+
) AS MinRevenueBeyond
965+
FROM
966+
t1
967+
WINDOW
968+
w1 AS (
969+
PARTITION BY
970+
department,
971+
division
972+
),
973+
w2 AS (
974+
w1
975+
ORDER BY
976+
hire_date
977+
);

tests/compress.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,5 @@
8989
WITH cte AS (SELECT a, b FROM table), RECURSIVE fibonacci (n, fib_n, next_fib_n) AS ( SELECT 1, 0, 1 UNION ALL SELECT n + 1, next_fib_n, fib_n + next_fib_n FROM fibonacci WHERE n < 10 ) SELECT * FROM fibonacci;
9090
---
9191
WITH cte1 AS (SELECT a, b FROM table1), cte2 AS (SELECT c, d FROM table2) SELECT b, d FROM cte1 JOIN cte2 WHERE cte1.a = cte2.c;
92+
---
93+
SELECT a, GROUP_CONCAT(b, '.') OVER (ORDER BY c GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) AS no_others, GROUP_CONCAT(b, '.') OVER (ORDER BY c GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) AS current_row, GROUP_CONCAT(b, '.') OVER (ORDER BY c GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE GROUP) AS grp, GROUP_CONCAT(b, '.') OVER (ORDER BY c GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE TIES) AS tie, GROUP_CONCAT(b, '.') FILTER (WHERE c != 'two') OVER (ORDER BY a) AS filtered, CONVERT(VARCHAR(20), AVG(SalesYTD) OVER (PARTITION BY TerritoryID ORDER BY DATEPART(yy, ModifiedDate)), 1) AS MovingAvg, AVG(starting_salary) OVER w2 AVG, MIN(starting_salary) OVER w2 MIN_STARTING_SALARY, MAX(starting_salary) OVER (w1 ORDER BY hire_date), LISTAGG(arg, ',') OVER (PARTITION BY part ORDER BY ord ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS LISTAGG_ROWS, LISTAGG(arg, ',') OVER (PARTITION BY part ORDER BY ord RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS LISTAGG_RANGE, MIN(Revenue) OVER (PARTITION BY DepartmentID ORDER BY RevenueYear ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS MinRevenueBeyond FROM t1 WINDOW w1 AS (PARTITION BY department, division), w2 AS (w1 ORDER BY hire_date);

0 commit comments

Comments
 (0)