1+ /*****************************************************************
2+ * Licensed to the Apache Software Foundation (ASF) under one
3+ * or more contributor license agreements. See the NOTICE file
4+ * distributed with this work for additional information
5+ * regarding copyright ownership. The ASF licenses this file
6+ * to you under the Apache License, Version 2.0 (the
7+ * "License"); you may not use this file except in compliance
8+ * with the License. You may obtain a copy of the License at
9+ *
10+ * https://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing,
13+ * software distributed under the License is distributed on an
14+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+ * KIND, either express or implied. See the License for the
16+ * specific language governing permissions and limitations
17+ * under the License.
18+ ****************************************************************/
19+
20+ package org .apache .cayenne .exp .parser ;
21+
22+ import org .apache .cayenne .ObjectContext ;
23+ import org .apache .cayenne .di .Inject ;
24+ import org .apache .cayenne .exp .Expression ;
25+ import org .apache .cayenne .exp .ExpressionException ;
26+ import org .apache .cayenne .exp .ExpressionFactory ;
27+ import org .apache .cayenne .query .ObjectSelect ;
28+ import org .apache .cayenne .test .jdbc .DBHelper ;
29+ import org .apache .cayenne .test .jdbc .TableHelper ;
30+ import org .apache .cayenne .testdo .testmap .Artist ;
31+ import org .apache .cayenne .testdo .testmap .Gallery ;
32+ import org .apache .cayenne .testdo .testmap .Painting ;
33+ import org .apache .cayenne .unit .di .DataChannelInterceptor ;
34+ import org .apache .cayenne .unit .di .runtime .CayenneProjects ;
35+ import org .apache .cayenne .unit .di .runtime .RuntimeCase ;
36+ import org .apache .cayenne .unit .di .runtime .UseCayenneRuntime ;
37+ import org .junit .Before ;
38+ import org .junit .Test ;
39+
40+ import java .util .List ;
41+
42+ import static org .junit .Assert .assertEquals ;
43+
44+ @ UseCayenneRuntime (CayenneProjects .TESTMAP_PROJECT )
45+ public class ASTNotExistsIT extends RuntimeCase {
46+
47+ @ Inject
48+ private ObjectContext context ;
49+
50+ @ Inject
51+ private DBHelper dbHelper ;
52+
53+ @ Inject
54+ private DataChannelInterceptor queryInterceptor ;
55+
56+ @ Before
57+ public void createArtistsDataSet () throws Exception {
58+ TableHelper tArtist = new TableHelper (dbHelper , "ARTIST" );
59+ tArtist .setColumns ("ARTIST_ID" , "ARTIST_NAME" , "DATE_OF_BIRTH" );
60+
61+ long dateBase = System .currentTimeMillis ();
62+ for (int i = 1 ; i <= 20 ; i ++) {
63+ tArtist .insert (i , "artist" + i , new java .sql .Date (dateBase + 10000 * i ));
64+ }
65+
66+ TableHelper tGallery = new TableHelper (dbHelper , "GALLERY" );
67+ tGallery .setColumns ("GALLERY_ID" , "GALLERY_NAME" );
68+ tGallery .insert (1 , "tate modern" );
69+
70+ TableHelper tPaintings = new TableHelper (dbHelper , "PAINTING" );
71+ tPaintings .setColumns ("PAINTING_ID" , "PAINTING_TITLE" , "ARTIST_ID" , "GALLERY_ID" );
72+ for (int i = 1 ; i <= 20 ; i ++) {
73+ tPaintings .insert (i , "painting" + i , i % 5 + 1 , 1 );
74+ }
75+ }
76+
77+ @ Test (expected = ExpressionException .class )
78+ public void testEvaluateInMemoryNotExistsSubquery () {
79+ ObjectSelect <Painting > subQuery = ObjectSelect .query (Painting .class )
80+ .where (Painting .TO_ARTIST .eq (Artist .ARTIST_ID_PK_PROPERTY .enclosing ()));
81+
82+ doEvaluateWithQuery (ExpressionFactory .notExists (subQuery ));
83+ }
84+
85+ @ Test
86+ public void testEvaluateInMemoryNotExistsExpression () {
87+ // doEvaluateNoQuery(Artist.PAINTING_ARRAY.notExists());
88+
89+ doEvaluateNoQuery (Artist .ARTIST_ID_PK_PROPERTY .eq (6L ).andExp (Artist .PAINTING_ARRAY .notExists ()));
90+
91+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .PAINTING_TITLE ).like ("p%" ).notExists ());
92+
93+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .PAINTING_TITLE ).like ("not_exists%" ).notExists ());
94+
95+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_PAINTING_INFO ).notExists ());
96+
97+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).notExists ());
98+
99+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).dot (Gallery .GALLERY_NAME ).like ("g%" ).notExists ());
100+
101+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).dot (Gallery .GALLERY_NAME ).like ("not_exists%" ).notExists ());
102+
103+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).dot (Gallery .GALLERY_NAME ).like ("g%" )
104+ .andExp (Artist .PAINTING_ARRAY .dot (Painting .PAINTING_TITLE ).like ("p%" ))
105+ .notExists ());
106+
107+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).dot (Gallery .GALLERY_NAME ).like ("not_exists%" )
108+ .andExp (Artist .PAINTING_ARRAY .dot (Painting .PAINTING_TITLE ).like ("p%" ))
109+ .notExists ());
110+
111+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).dot (Gallery .GALLERY_NAME ).like ("g%" )
112+ .andExp (Artist .PAINTING_ARRAY .dot (Painting .PAINTING_TITLE ).like ("not_exists%" ))
113+ .notExists ());
114+
115+ doEvaluateNoQuery (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).dot (Gallery .GALLERY_NAME ).like ("not_exists%" )
116+ .andExp (Artist .PAINTING_ARRAY .dot (Painting .PAINTING_TITLE ).like ("not_exists%" ))
117+ .notExists ());
118+
119+ }
120+
121+ private void doEvaluateNoQuery (Expression exp ) {
122+ List <Artist > artistSelected = ObjectSelect .query (Artist .class , exp )
123+ .orderBy (Artist .ARTIST_ID_PK_PROPERTY .asc ())
124+ .select (context );
125+
126+ List <Artist > artists = ObjectSelect .query (Artist .class )
127+ .prefetch (Artist .PAINTING_ARRAY .outer ().disjoint ())
128+ .prefetch (Artist .PAINTING_ARRAY .outer ().dot (Painting .TO_PAINTING_INFO ).disjoint ())
129+ .prefetch (Artist .PAINTING_ARRAY .outer ().dot (Painting .TO_GALLERY ).disjoint ())
130+ .orderBy (Artist .ARTIST_ID_PK_PROPERTY .asc ())
131+ .select (context );
132+
133+ queryInterceptor .runWithQueriesBlocked (() -> {
134+ List <Artist > artistsFiltered = exp .filterObjects (artists );
135+ assertEquals (exp .toString (), artistSelected , artistsFiltered );
136+ });
137+ }
138+
139+ private void doEvaluateWithQuery (Expression exp ) {
140+ List <Artist > artistSelected = ObjectSelect .query (Artist .class , exp ).select (context );
141+
142+ List <Artist > artists = ObjectSelect .query (Artist .class )
143+ .prefetch (Artist .PAINTING_ARRAY .disjoint ())
144+ .prefetch (Artist .PAINTING_ARRAY .dot (Painting .TO_PAINTING_INFO ).disjoint ())
145+ .prefetch (Artist .PAINTING_ARRAY .dot (Painting .TO_GALLERY ).disjoint ())
146+ .orderBy (Artist .ARTIST_ID_PK_PROPERTY .asc ())
147+ .select (context );
148+
149+ List <Artist > artistsFiltered = exp .filterObjects (artists );
150+ assertEquals (exp .toString (), artistSelected , artistsFiltered );
151+ }
152+ }
0 commit comments