11
11
import java .util .HashSet ;
12
12
import java .util .List ;
13
13
import java .util .Map ;
14
+ import java .util .Optional ;
14
15
import java .util .Set ;
15
16
import java .util .stream .Stream ;
16
17
import org .apache .lucene .search .TotalHits ;
@@ -96,61 +97,90 @@ public void run() throws IOException, SqlParseException {
96
97
97
98
LOG .debug ("🔍 Starting join execution, checking for JOIN_TIME_OUT hints..." );
98
99
99
- // ✅ Extract JOIN_TIME_OUT hint and create PIT with custom keepalive
100
- TimeValue customKeepAlive = extractJoinTimeoutFromHints ();
100
+ // ✅ Create PIT with appropriate timeout
101
+ createPointInTimeWithCustomTimeout ();
101
102
102
- if (customKeepAlive != null ) {
103
- LOG .info (
104
- "✅ Using custom PIT keepalive from JOIN_TIME_OUT hint: {} seconds ({}ms)" ,
105
- customKeepAlive .getSeconds (),
106
- customKeepAlive .getMillis ());
107
- pit = new PointInTimeHandlerImpl (client , indices , customKeepAlive );
108
- } else {
109
- LOG .info ("⚠️ No JOIN_TIME_OUT hint found, using default PIT keepalive" );
110
- pit = new PointInTimeHandlerImpl (client , indices );
111
- }
112
-
113
- pit .create ();
103
+ // Execute the query
114
104
results = innerRun ();
105
+
106
+ // Record execution time
115
107
long joinTimeInMilli = System .currentTimeMillis () - timeBefore ;
116
108
this .metaResults .setTookImMilli (joinTimeInMilli );
117
- } catch (Exception e ) {
118
- LOG .error ("Failed during join query run." , e );
109
+
110
+ } catch (IOException e ) {
111
+ LOG .error ("IO error during join query execution" , e );
112
+ throw e ;
113
+ } catch (SqlParseException e ) {
114
+ LOG .error ("SQL parsing error during join query execution" , e );
115
+ throw e ;
116
+ } catch (RuntimeException e ) {
117
+ LOG .error ("Runtime error during join query execution" , e );
119
118
throw new IllegalStateException ("Error occurred during join query run" , e );
119
+ } catch (Exception e ) {
120
+ LOG .error ("Unexpected error during join query execution" , e );
121
+ throw new IllegalStateException ("Unexpected error occurred during join query run" , e );
120
122
} finally {
123
+ cleanupPointInTime ();
124
+ }
125
+ }
126
+
127
+ /** Create Point-in-Time with custom timeout if JOIN_TIME_OUT hint is present */
128
+ private void createPointInTimeWithCustomTimeout () {
129
+ Optional <TimeValue > customKeepAlive = extractJoinTimeoutFromHints ();
130
+
131
+ if (customKeepAlive .isPresent ()) {
132
+ TimeValue keepAlive = customKeepAlive .get ();
133
+ LOG .info (
134
+ "✅ Using custom PIT keepalive from JOIN_TIME_OUT hint: {} seconds ({}ms)" ,
135
+ keepAlive .getSeconds (),
136
+ keepAlive .getMillis ());
137
+ pit = new PointInTimeHandlerImpl (client , indices , keepAlive );
138
+ } else {
139
+ LOG .info ("⚠️ No JOIN_TIME_OUT hint found, using default PIT keepalive" );
140
+ pit = new PointInTimeHandlerImpl (client , indices );
141
+ }
142
+
143
+ pit .create ();
144
+ }
145
+
146
+ /** Clean up Point-in-Time resources safely */
147
+ private void cleanupPointInTime () {
148
+ if (pit != null ) {
121
149
try {
122
150
pit .delete ();
151
+ LOG .debug ("Successfully deleted PIT" );
123
152
} catch (RuntimeException e ) {
124
153
Metrics .getInstance ().getNumericalMetric (MetricName .FAILED_REQ_COUNT_SYS ).increment ();
125
- LOG .error ("Error deleting point in time {} " , pit );
154
+ LOG .error ("Error deleting point in time: {}" , e . getMessage (), e );
126
155
}
127
156
}
128
157
}
129
158
130
- protected TimeValue extractJoinTimeoutFromHints () {
159
+ protected Optional < TimeValue > extractJoinTimeoutFromHints () {
131
160
try {
132
161
LOG .debug (
133
162
"Starting hint extraction from request builder: {}" ,
134
163
requestBuilder != null ? requestBuilder .getClass ().getSimpleName () : "null" );
135
164
136
165
// Check first table for hints
137
- TimeValue timeout = extractJoinTimeoutFromTable ("firstTable" , requestBuilder .getFirstTable ());
138
- if (timeout != null ) {
166
+ Optional <TimeValue > timeout =
167
+ extractJoinTimeoutFromTable ("firstTable" , requestBuilder .getFirstTable ());
168
+ if (timeout .isPresent ()) {
139
169
return timeout ;
140
170
}
141
171
142
172
// Check second table for hints if not found in first
143
173
timeout = extractJoinTimeoutFromTable ("secondTable" , requestBuilder .getSecondTable ());
144
- if (timeout != null ) {
174
+ if (timeout . isPresent () ) {
145
175
return timeout ;
146
176
}
147
177
148
178
LOG .debug ("No JOIN_TIME_OUT hint found in either table" );
149
- return null ;
179
+ return Optional . empty () ;
150
180
151
181
} catch (Exception e ) {
152
182
LOG .warn ("Error extracting JOIN_TIME_OUT hint, using default keepalive" , e );
153
- return null ;
183
+ return Optional . empty () ;
154
184
}
155
185
}
156
186
@@ -159,50 +189,54 @@ protected TimeValue extractJoinTimeoutFromHints() {
159
189
*
160
190
* @param tableName descriptive name for logging (e.g., "firstTable", "secondTable")
161
191
* @param table the table request builder to examine
162
- * @return TimeValue if JOIN_TIME_OUT hint found, null otherwise
192
+ * @return Optional containing TimeValue if JOIN_TIME_OUT hint found, empty otherwise
163
193
*/
164
- private TimeValue extractJoinTimeoutFromTable (String tableName , TableInJoinRequestBuilder table ) {
194
+ private Optional <TimeValue > extractJoinTimeoutFromTable (
195
+ String tableName , TableInJoinRequestBuilder table ) {
165
196
if (table == null ) {
166
197
LOG .debug ("{} is null" , tableName );
167
- return null ;
198
+ return Optional . empty () ;
168
199
}
169
200
170
201
Select originalSelect = table .getOriginalSelect ();
171
202
if (originalSelect == null ) {
172
203
LOG .debug ("{}.getOriginalSelect() is null" , tableName );
173
- return null ;
204
+ return Optional . empty () ;
174
205
}
175
206
176
207
List <Hint > hints = originalSelect .getHints ();
177
208
int hintCount = hints != null ? hints .size () : 0 ;
178
209
LOG .debug ("{} has {} hints" , tableName , hintCount );
179
210
180
- if (hints != null && !hints .isEmpty ()) {
181
- LOG .debug ("Examining hints in {}:" , tableName );
182
- for (int i = 0 ; i < hints .size (); i ++) {
183
- Hint hint = hints .get (i );
184
- LOG .debug (
185
- " Hint[{}]: type={}, params={}" ,
186
- i ,
187
- hint .getType (),
188
- hint .getParams () != null ? java .util .Arrays .toString (hint .getParams ()) : "null" );
189
-
190
- // Check if this is the JOIN_TIME_OUT hint we're looking for
191
- if (hint .getType () == HintType .JOIN_TIME_OUT ) {
192
- Object [] params = hint .getParams ();
193
- if (params != null && params .length > 0 ) {
194
- Integer timeoutSeconds = (Integer ) params [0 ];
195
- LOG .info ("Found JOIN_TIME_OUT hint in {}: {} seconds" , tableName , timeoutSeconds );
196
- return TimeValue .timeValueSeconds (timeoutSeconds );
197
- } else {
198
- LOG .warn ("JOIN_TIME_OUT hint found in {} but has no parameters" , tableName );
199
- }
211
+ if (hints == null || hints .isEmpty ()) {
212
+ LOG .debug ("No hints found in {}" , tableName );
213
+ return Optional .empty ();
214
+ }
215
+
216
+ LOG .debug ("Examining hints in {}:" , tableName );
217
+ for (int i = 0 ; i < hints .size (); i ++) {
218
+ Hint hint = hints .get (i );
219
+ LOG .debug (
220
+ " Hint[{}]: type={}, params={}" ,
221
+ i ,
222
+ hint .getType (),
223
+ hint .getParams () != null ? java .util .Arrays .toString (hint .getParams ()) : "null" );
224
+
225
+ // Check if this is the JOIN_TIME_OUT hint we're looking for
226
+ if (hint .getType () == HintType .JOIN_TIME_OUT ) {
227
+ Object [] params = hint .getParams ();
228
+ if (params != null && params .length > 0 ) {
229
+ Integer timeoutSeconds = (Integer ) params [0 ];
230
+ LOG .info ("Found JOIN_TIME_OUT hint in {}: {} seconds" , tableName , timeoutSeconds );
231
+ return Optional .of (TimeValue .timeValueSeconds (timeoutSeconds ));
232
+ } else {
233
+ LOG .warn ("JOIN_TIME_OUT hint found in {} but has no parameters" , tableName );
200
234
}
201
235
}
202
236
}
203
237
204
238
LOG .debug ("No JOIN_TIME_OUT hint found in {}" , tableName );
205
- return null ;
239
+ return Optional . empty () ;
206
240
}
207
241
208
242
protected abstract List <SearchHit > innerRun () throws IOException , SqlParseException ;
0 commit comments