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]

Reply via email to