@@ -99,6 +99,8 @@ public enum Hook implements HookAnchor
99
99
/** Anchor for the " HAVING " sub-clause (only possible if there is a
100
100
GROUP BY clause) */
101
101
HAVING ,
102
+ /** Anchor for the " WINDOW " clause */
103
+ WINDOW ,
102
104
/** Anchor for the " ORDER BY " clause */
103
105
ORDER_BY ,
104
106
/** Anchor for the " FOR UPDATE " clause */
@@ -117,6 +119,7 @@ public enum Hook implements HookAnchor
117
119
private SqlObjectList <SqlObject > _grouping = SqlObjectList .create ();
118
120
private SqlObjectList <SqlObject > _ordering = SqlObjectList .create ();
119
121
private ComboCondition _having = ComboCondition .and ();
122
+ private SqlObjectList <SqlObject > _windows = SqlObjectList .create ();
120
123
private SqlObject _offset ;
121
124
private SqlObject _fetchCount ;
122
125
@@ -424,8 +427,7 @@ public ComboCondition getHavingClause() {
424
427
/**
425
428
* Adds a condition to the HAVING clause for the select query (AND'd with
426
429
* any other HAVING conditions). Note that the HAVING clause will only be
427
- * generated if some conditions have
428
- been added.
430
+ * generated if some conditions have been added.
429
431
* <p>
430
432
* For convenience purposes, the SelectQuery generates it's own
431
433
* ComboCondition allowing multiple HAVING conditions to be AND'd together.
@@ -437,12 +439,26 @@ public SelectQuery addHaving(Condition newCondition) {
437
439
return this ;
438
440
}
439
441
442
+ /**
443
+ * Adds a named window definition to the select query's WINDOW definitions
444
+ * <p>
445
+ * {@code Object} -> {@code SqlObject} conversions handled by
446
+ * {@link Converter#toCustomSqlObject}.
447
+ * @see "SQL 2003"
448
+ */
449
+ public SelectQuery addWindowDefinition (String name , Object window ) {
450
+ _windows .addObject (new NamedWindowDefinition (
451
+ name , Converter .toCustomSqlObject (window )));
452
+ return this ;
453
+ }
454
+
440
455
/**
441
456
* Sets the value for the "OFFSET" clause. Note that this clause is defined
442
457
* in "SQL 2008".
443
458
* <p>
444
459
* {@code Object} -> {@code SqlObject} conversions handled by
445
460
* {@link Converter#toValueSqlObject}.
461
+ * @see "SQL 2008"
446
462
*/
447
463
public SelectQuery setOffset (Object offset ) {
448
464
_offset = Converter .toValueSqlObject (offset );
@@ -455,6 +471,7 @@ public SelectQuery setOffset(Object offset) {
455
471
* <p>
456
472
* {@code Object} -> {@code SqlObject} conversions handled by
457
473
* {@link Converter#toValueSqlObject}.
474
+ * @see "SQL 2008"
458
475
*/
459
476
public SelectQuery setFetchNext (Object fetchCount ) {
460
477
_fetchCount = Converter .toValueSqlObject (fetchCount );
@@ -489,14 +506,15 @@ public SelectQuery addCustomization(CustomSyntax obj) {
489
506
}
490
507
491
508
@ Override
492
- protected void collectSchemaObjects (ValidationContext vContext ) {
509
+ protected void collectSchemaObjects (ValidationContext vContext ) {
493
510
super .collectSchemaObjects (vContext );
494
511
_joins .collectSchemaObjects (vContext );
495
512
_columns .collectSchemaObjects (vContext );
496
513
_condition .collectSchemaObjects (vContext );
497
514
_grouping .collectSchemaObjects (vContext );
498
515
_ordering .collectSchemaObjects (vContext );
499
516
_having .collectSchemaObjects (vContext );
517
+ _windows .collectSchemaObjects (vContext );
500
518
if (_offset != null ) {
501
519
_offset .collectSchemaObjects (vContext );
502
520
}
@@ -506,7 +524,7 @@ protected void collectSchemaObjects(ValidationContext vContext) {
506
524
}
507
525
508
526
@ Override
509
- public void validate (ValidationContext vContext )
527
+ public void validate (ValidationContext vContext )
510
528
throws ValidationException
511
529
{
512
530
// if we have joins, check the tables, otherwise, the join tables will
@@ -624,7 +642,7 @@ private static void validateValue(SqlObject valueObj, String type, int minVal) {
624
642
}
625
643
626
644
@ Override
627
- protected void appendTo (AppendableExt app , SqlContext newContext )
645
+ protected void appendTo (AppendableExt app , SqlContext newContext )
628
646
throws IOException
629
647
{
630
648
newContext .setUseTableAliases (true );
@@ -658,6 +676,9 @@ protected void appendTo(AppendableExt app, SqlContext newContext)
658
676
// BY clause)
659
677
maybeAppendTo (app , Hook .HAVING , " HAVING " , _having , !_having .isEmpty ());
660
678
}
679
+
680
+ // append window definition clauses
681
+ maybeAppendTo (app , Hook .WINDOW , " WINDOW " , _windows , !_windows .isEmpty ());
661
682
662
683
// append ordering clause
663
684
maybeAppendTo (app , Hook .ORDER_BY , " ORDER BY " , _ordering ,
@@ -742,7 +763,7 @@ static boolean hasAllColumns(SqlObjectList<? extends SqlObject> columns) {
742
763
* Outputs the right side of a join clause
743
764
* <code>"<joinType> <toTable> ON <joinCondition>"</code>.
744
765
*/
745
- private static class JoinTo extends SqlObject
766
+ private static final class JoinTo extends SqlObject
746
767
{
747
768
private SqlObject _toTable ;
748
769
private JoinType _joinType ;
@@ -793,7 +814,30 @@ public void appendTo(AppendableExt app) throws IOException {
793
814
app .append (", " ).append (_toTable );
794
815
}
795
816
}
796
-
797
817
}
798
818
819
+ /**
820
+ * Outputs a named window definition clause like
821
+ * <code>"<name> AS <windowDefinition>"</code>.
822
+ */
823
+ private static final class NamedWindowDefinition extends SqlObject
824
+ {
825
+ private final String _name ;
826
+ private final SqlObject _definition ;
827
+
828
+ private NamedWindowDefinition (String name , SqlObject definition ) {
829
+ _name = name ;
830
+ _definition = definition ;
831
+ }
832
+
833
+ @ Override
834
+ protected void collectSchemaObjects (ValidationContext vContext ) {
835
+ _definition .collectSchemaObjects (vContext );
836
+ }
837
+
838
+ @ Override
839
+ public void appendTo (AppendableExt app ) throws IOException {
840
+ app .append (_name ).append (" AS " ).append (_definition );
841
+ }
842
+ }
799
843
}
0 commit comments