|
234 | 234 | import com.starrocks.sql.ast.expression.ExprToSql; |
235 | 235 | import com.starrocks.sql.ast.expression.LikePredicate; |
236 | 236 | import com.starrocks.sql.ast.expression.LimitElement; |
237 | | -import com.starrocks.sql.ast.expression.Predicate; |
238 | 237 | import com.starrocks.sql.ast.expression.SlotRef; |
239 | 238 | import com.starrocks.sql.ast.expression.StringLiteral; |
240 | 239 | import com.starrocks.sql.ast.group.ShowCreateGroupProviderStmt; |
|
248 | 247 | import com.starrocks.sql.ast.warehouse.ShowNodesStmt; |
249 | 248 | import com.starrocks.sql.ast.warehouse.ShowWarehousesStmt; |
250 | 249 | import com.starrocks.sql.common.MetaUtils; |
| 250 | +import com.starrocks.sql.common.UnsupportedException; |
| 251 | +import com.starrocks.sql.optimizer.operator.scalar.ConstantOperator; |
| 252 | +import com.starrocks.sql.optimizer.operator.scalar.ScalarOperator; |
| 253 | +import com.starrocks.sql.optimizer.rewrite.ScalarOperatorRewriter; |
251 | 254 | import com.starrocks.sql.optimizer.rule.transformation.materialization.MvUtils; |
| 255 | +import com.starrocks.sql.optimizer.transformer.SqlToScalarOperatorTranslator; |
252 | 256 | import com.starrocks.sql.spm.SPMStmtExecutor; |
253 | 257 | import com.starrocks.statistic.AnalyzeJob; |
254 | 258 | import com.starrocks.statistic.AnalyzeStatus; |
|
299 | 303 | import java.util.concurrent.TimeUnit; |
300 | 304 | import java.util.concurrent.atomic.AtomicBoolean; |
301 | 305 | import java.util.stream.Collectors; |
| 306 | +import java.util.stream.Stream; |
302 | 307 |
|
303 | 308 | // Execute one show statement. |
304 | 309 | public class ShowExecutor { |
@@ -312,7 +317,80 @@ public ShowExecutor(ShowExecutorVisitor showExecutorVisitor) { |
312 | 317 | } |
313 | 318 |
|
314 | 319 | public static ShowResultSet execute(ShowStmt statement, ConnectContext context) { |
315 | | - return GlobalStateMgr.getCurrentState().getShowExecutor().showExecutorVisitor.visit(statement, context); |
| 320 | + ShowResultSet result = GlobalStateMgr.getCurrentState().getShowExecutor().showExecutorVisitor.visit(statement, context); |
| 321 | + List<List<String>> datas = doPredicate(statement, result); |
| 322 | + datas = doOrderByLimit(statement, datas); |
| 323 | + result.setResultRows(datas); |
| 324 | + return result; |
| 325 | + } |
| 326 | + |
| 327 | + private static List<List<String>> doOrderByLimit(ShowStmt statement, List<List<String>> datas) { |
| 328 | + if (!statement.isSelfOrderBy() && CollectionUtils.isNotEmpty(statement.getOrderByPairs())) { |
| 329 | + OrderByPair[] orderByPairArr = statement.getOrderByPairs().toArray(new OrderByPair[0]); |
| 330 | + datas.sort((row1, row2) -> { |
| 331 | + for (OrderByPair pair : orderByPairArr) { |
| 332 | + int index = pair.getIndex(); |
| 333 | + if (index >= row1.size() || index >= row2.size()) { |
| 334 | + continue; |
| 335 | + } |
| 336 | + String val1 = row1.get(index); |
| 337 | + String val2 = row2.get(index); |
| 338 | + |
| 339 | + int cmp; |
| 340 | + try { |
| 341 | + double d1 = Double.parseDouble(val1); |
| 342 | + double d2 = Double.parseDouble(val2); |
| 343 | + cmp = Double.compare(d1, d2); |
| 344 | + } catch (NumberFormatException e) { |
| 345 | + cmp = val1.compareTo(val2); |
| 346 | + } |
| 347 | + if (cmp != 0) { |
| 348 | + return pair.isDesc() ? -cmp : cmp; |
| 349 | + } |
| 350 | + } |
| 351 | + return 0; |
| 352 | + }); |
| 353 | + } |
| 354 | + if (!statement.isSelfLimit() && statement.getLimitElement() != null) { |
| 355 | + LimitElement le = statement.getLimitElement(); |
| 356 | + Stream<List<String>> stream = datas.stream(); |
| 357 | + if (le.hasOffset()) { |
| 358 | + stream = stream.skip(le.getOffset()); |
| 359 | + } |
| 360 | + if (le.hasLimit()) { |
| 361 | + stream = stream.limit(le.getLimit()); |
| 362 | + } |
| 363 | + datas = stream.collect(Collectors.toList()); |
| 364 | + } |
| 365 | + return datas; |
| 366 | + } |
| 367 | + |
| 368 | + private static List<List<String>> doPredicate(ShowStmt statement, ShowResultSet result) { |
| 369 | + if (statement.isSelfPredicate() || statement.getPredicate() == null) { |
| 370 | + return result.getResultRows(); |
| 371 | + } |
| 372 | + // build columns |
| 373 | + List<List<String>> datas = Lists.newArrayList(); |
| 374 | + Map<String, ScalarOperator> valuesMappings = Maps.newHashMap(); |
| 375 | + for (List<String> rows : result.getResultRows()) { |
| 376 | + valuesMappings.clear(); |
| 377 | + for (int index = 0; index < result.getMetaData().getColumns().size(); index++) { |
| 378 | + Column c = result.getMetaData().getColumn(index); |
| 379 | + valuesMappings.put(c.getName().toLowerCase(), ConstantOperator.createVarchar(rows.get(index))); |
| 380 | + } |
| 381 | + ScalarOperator p = SqlToScalarOperatorTranslator.translateWithSlotRef(statement.getPredicate(), |
| 382 | + slotRef -> valuesMappings.get(slotRef.getColumnName().toLowerCase())); |
| 383 | + ScalarOperatorRewriter re = new ScalarOperatorRewriter(); |
| 384 | + ScalarOperator r = re.rewrite(p, ScalarOperatorRewriter.DEFAULT_REWRITE_RULES); |
| 385 | + |
| 386 | + if (!r.isConstantRef()) { |
| 387 | + throw UnsupportedException.unsupportedException( |
| 388 | + "doesn't support predicate: " + ExprToSql.toMySql(statement.getPredicate())); |
| 389 | + } else if (r.isConstantTrue()) { |
| 390 | + datas.add(rows); |
| 391 | + } |
| 392 | + } |
| 393 | + return datas; |
316 | 394 | } |
317 | 395 |
|
318 | 396 | public static class ShowExecutorVisitor implements AstVisitorExtendInterface<ShowResultSet, ConnectContext> { |
@@ -3090,7 +3168,7 @@ public ShowResultSet visitShowNodesStatement(ShowNodesStmt statement, ConnectCon |
3090 | 3168 | private List<List<String>> doPredicate(ShowStmt showStmt, |
3091 | 3169 | ShowResultSetMetaData showResultSetMetaData, |
3092 | 3170 | List<List<String>> rows) { |
3093 | | - Predicate predicate = showStmt.getPredicate(); |
| 3171 | + Expr predicate = showStmt.getPredicate(); |
3094 | 3172 | if (predicate == null) { |
3095 | 3173 | return rows; |
3096 | 3174 | } |
|