This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push:
new ff4284f [feature](hint)(mysql-compatibility) Support general hints in
select statement (#7664)
ff4284f is described below
commit ff4284f3fa3680fc4a9af6758e79cb382b423614
Author: vinson0526 <[email protected]>
AuthorDate: Sun Jan 9 16:59:08 2022 +0800
[feature](hint)(mysql-compatibility) Support general hints in select
statement (#7664)
Support general hints.
Sql example:
```sql
SELECT /*+ one_hint(1000000) another_hint(k = "v")*/ 1;
```
hints syntax is:
```
/*+ [ HINT_NAME( [ key [ =value ]? ]* ) ]+ */
```
- support multi hints, sep with space
- hint name could be any string in identifier format
- hint could have zero or more parameters, sep with comma
- hint parameter must have one key
- hint parameter could have zero or one value
- hint parameter‘s key and value connected by equal sign
---
fe/fe-core/src/main/cup/sql_parser.cup | 74 +++++++++++++++++++---
.../java/org/apache/doris/analysis/SelectList.java | 8 ++-
fe/fe-core/src/main/jflex/sql_scanner.flex | 1 -
.../org/apache/doris/analysis/SelectStmtTest.java | 29 +++++++++
4 files changed, 100 insertions(+), 12 deletions(-)
diff --git a/fe/fe-core/src/main/cup/sql_parser.cup
b/fe/fe-core/src/main/cup/sql_parser.cup
index 236fbfb..4589c2c 100644
--- a/fe/fe-core/src/main/cup/sql_parser.cup
+++ b/fe/fe-core/src/main/cup/sql_parser.cup
@@ -18,10 +18,12 @@
package org.apache.doris.analysis;
import java.math.BigDecimal;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import org.apache.doris.analysis.AlterDatabaseQuotaStmt.QuotaType;
@@ -261,7 +263,7 @@ terminal String KW_ADD, KW_ADMIN, KW_AFTER, KW_AGGREGATE,
KW_ALIAS, KW_ALL, KW_A
KW_RANDOM, KW_RANGE, KW_READ, KW_RECOVER, KW_REGEXP, KW_RELEASE, KW_RENAME,
KW_REPAIR, KW_REPEATABLE, KW_REPOSITORY, KW_REPOSITORIES, KW_REPLACE,
KW_REPLACE_IF_NOT_NULL, KW_REPLICA, KW_RESOURCE, KW_RESOURCES, KW_RESTORE,
KW_RETURNS, KW_RESUME, KW_REVOKE,
KW_RIGHT, KW_ROLE, KW_ROLES, KW_ROLLBACK, KW_ROLLUP, KW_ROUTINE, KW_ROW,
KW_ROWS,
- KW_S3, KW_SCHEMA, KW_SCHEMAS, KW_SECOND, KW_SELECT, KW_SEMI,
KW_SERIALIZABLE, KW_SESSION, KW_SET, KW_SETS, KW_SET_VAR, KW_SHOW, KW_SIGNED,
+ KW_S3, KW_SCHEMA, KW_SCHEMAS, KW_SECOND, KW_SELECT, KW_SEMI,
KW_SERIALIZABLE, KW_SESSION, KW_SET, KW_SETS, KW_SHOW, KW_SIGNED,
KW_SKEW,
KW_SMALLINT, KW_SNAPSHOT, KW_SONAME, KW_SPLIT, KW_START, KW_STATUS,
KW_STATS, KW_STOP, KW_STORAGE, KW_STREAM, KW_STRING, KW_STRUCT,
KW_SUM, KW_SUPERUSER, KW_SYNC, KW_SYSTEM,
@@ -398,7 +400,12 @@ nonterminal InlineViewRef inline_view_ref;
nonterminal JoinOperator join_operator;
nonterminal ArrayList<String> opt_plan_hints;
nonterminal ArrayList<String> opt_sort_hints;
-nonterminal HashMap<String, String> select_hints_list, opt_select_hints;
+nonterminal Map<String, Map<String, String>> opt_select_hints;
+nonterminal Map<String, Map<String, String>> query_hints;
+nonterminal Map.Entry<String, Map<String, String>> query_hint;
+nonterminal Map<String, String> query_hint_parameters;
+nonterminal Map.Entry<String, String> query_hint_parameter;
+nonterminal String query_hint_parameter_key;
nonterminal Expr sign_chain_expr;
nonterminal Qualifier opt_set_qualifier;
nonterminal Operation set_op;
@@ -3851,16 +3858,65 @@ select_clause ::=
:}
;
-select_hints_list ::=
- select_hints_list:map COMMA variable_name:k equal literal_or_ident:v
+query_hint_parameter_key ::=
+ literal:k
{:
- map.put(k, v);
+ RESULT = k.getStringValue();
+ :}
+ | variable_name:k
+ {:
+ RESULT = k;
+ :}
+ ;
+
+query_hint_parameter ::=
+ query_hint_parameter_key:k
+ {:
+ RESULT = new AbstractMap.SimpleEntry<String, String>(k, null);
+ :}
+ | query_hint_parameter_key:k equal literal_or_ident:v
+ {:
+ RESULT = new AbstractMap.SimpleEntry<String, String>(k, v);
+ :}
+ ;
+
+
+query_hint_parameters ::=
+ query_hint_parameters:map COMMA query_hint_parameter:kv
+ {:
+ map.put(kv.getKey(), kv.getValue());
+ RESULT = map;
+ :}
+ | query_hint_parameter:kv
+ {:
+ Map<String, String> map = new HashMap<>();
+ map.put(kv.getKey(), kv.getValue());
+ RESULT = map;
+ :}
+ |
+ {:
+ RESULT = new HashMap<String, String>();
+ :}
+ ;
+
+query_hint ::=
+ ident:k LPAREN query_hint_parameters:v RPAREN
+ {:
+ RESULT = new AbstractMap.SimpleEntry<String, Map<String,
String>>(k.toLowerCase(Locale.ROOT), v);
+ :}
+ ;
+
+query_hints ::=
+ query_hints:map query_hint:kv
+ {:
+ map.computeIfAbsent(kv.getKey(), k -> new HashMap<>());
+ map.get(kv.getKey()).putAll(kv.getValue());
RESULT = map;
:}
- | variable_name:k equal literal_or_ident:v
+ | query_hint:kv
{:
- HashMap<String, String> map = new HashMap<String, String>();
- map.put(k, v);
+ Map<String, Map<String, String>> map = new HashMap<>();
+ map.put(kv.getKey(), kv.getValue());
RESULT = map;
:}
;
@@ -3877,7 +3933,7 @@ literal_or_ident ::=
;
opt_select_hints ::=
- COMMENTED_PLAN_HINT_START KW_SET_VAR LPAREN select_hints_list:map RPAREN
COMMENTED_PLAN_HINT_END
+ COMMENTED_PLAN_HINT_START query_hints:map COMMENTED_PLAN_HINT_END
{:
RESULT = map;
:}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectList.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectList.java
index afa7dce..10d3606 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectList.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectList.java
@@ -30,6 +30,8 @@ import java.util.Map;
* Select list items plus distinct clause.
*/
public class SelectList {
+ private static final String SET_VAR_KEY = "set_var";
+
private boolean isDistinct;
private Map<String, String> optHints;
@@ -79,8 +81,10 @@ public class SelectList {
return optHints;
}
- public void setOptHints(Map<String, String> optHints) {
- this.optHints = optHints;
+ public void setOptHints(Map<String, Map<String, String>> optHints) {
+ if (optHints != null) {
+ this.optHints = optHints.get(SET_VAR_KEY);
+ }
}
public void reset() {
diff --git a/fe/fe-core/src/main/jflex/sql_scanner.flex
b/fe/fe-core/src/main/jflex/sql_scanner.flex
index a4945e2..e316512 100644
--- a/fe/fe-core/src/main/jflex/sql_scanner.flex
+++ b/fe/fe-core/src/main/jflex/sql_scanner.flex
@@ -349,7 +349,6 @@ import org.apache.doris.qe.SqlModeHelper;
keywordMap.put("serializable", new
Integer(SqlParserSymbols.KW_SERIALIZABLE));
keywordMap.put("session", new Integer(SqlParserSymbols.KW_SESSION));
keywordMap.put("set", new Integer(SqlParserSymbols.KW_SET));
- keywordMap.put("set_var", new Integer(SqlParserSymbols.KW_SET_VAR));
keywordMap.put("sets", new Integer(SqlParserSymbols.KW_SETS));
keywordMap.put("show", new Integer(SqlParserSymbols.KW_SHOW));
keywordMap.put("signed", new Integer(SqlParserSymbols.KW_SIGNED));
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java
b/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java
index 2246790..ecb5800 100755
--- a/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java
@@ -524,6 +524,35 @@ public class SelectStmtTest {
}
@Test
+ public void testSelectHints() throws Exception {
+ ConnectContext ctx = UtFrameUtils.createDefaultCtx();
+
+ // hint with integer literal parameter
+ String sql = "select /*+ common_hint(1) */ 1";
+ UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
+
+ // hint with float literal parameter
+ sql = "select /*+ common_hint(1.1) */ 1";
+ UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
+
+ // hint with string literal parameter
+ sql = "select /*+ common_hint(\"string\") */ 1";
+ UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
+
+ // hint with key value parameter
+ sql = "select /*+ common_hint(k = \"v\") */ 1";
+ UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
+
+ // hint with multi-parameters
+ sql = "select /*+ common_hint(1, 1.1, \"string\") */ 1";
+ UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
+
+ // multi-hints
+ sql = "select /*+ common_hint(1) another_hint(2) */ 1";
+ UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
+ }
+
+ @Test
public void testSelectHintSetVar() throws Exception {
String sql = "SELECT sleep(3);";
Planner planner =
dorisAssert.query(sql).internalExecuteOneAndGetPlan();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]