This is an automated email from the ASF dual-hosted git repository.

karan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new ccc55ef899 Mask SQL String in the MSQTaskQueryMaker for secrets 
(#13231)
ccc55ef899 is described below

commit ccc55ef8991716bc721b9ee0ab75c19a78a763a2
Author: Laksh Singla <[email protected]>
AuthorDate: Thu Nov 3 15:27:28 2022 +0530

    Mask SQL String in the MSQTaskQueryMaker for secrets (#13231)
    
    * add test
    
    * add masking code
    
    * fix test
    
    * oops
    
    * refactor json usage
    
    * refactor, variable update
    
    * add test cases
    
    * Trigger Build
    
    * add comment to the regex
    
    * address review comment
---
 .../apache/druid/msq/sql/MSQTaskQueryMaker.java    |  26 +--
 .../druid/msq/util/MSQTaskQueryMakerUtils.java     |  93 +++++++++++
 .../druid/msq/sql/MSQTaskQueryMakerTest.java       |  53 ------
 .../druid/msq/util/MSQTaskQueryMakerUtilsTest.java | 183 +++++++++++++++++++++
 4 files changed, 280 insertions(+), 75 deletions(-)

diff --git 
a/extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/sql/MSQTaskQueryMaker.java
 
b/extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/sql/MSQTaskQueryMaker.java
index 6beb0763bf..2430d34e3a 100644
--- 
a/extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/sql/MSQTaskQueryMaker.java
+++ 
b/extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/sql/MSQTaskQueryMaker.java
@@ -41,6 +41,7 @@ import org.apache.druid.msq.indexing.MSQDestination;
 import org.apache.druid.msq.indexing.MSQSpec;
 import org.apache.druid.msq.indexing.MSQTuningConfig;
 import org.apache.druid.msq.indexing.TaskReportMSQDestination;
+import org.apache.druid.msq.util.MSQTaskQueryMakerUtils;
 import org.apache.druid.msq.util.MultiStageQueryContext;
 import org.apache.druid.query.QueryContext;
 import org.apache.druid.query.QueryContexts;
@@ -48,7 +49,6 @@ import org.apache.druid.query.aggregation.AggregatorFactory;
 import org.apache.druid.rpc.indexing.OverlordClient;
 import org.apache.druid.segment.DimensionHandlerUtils;
 import org.apache.druid.segment.IndexSpec;
-import org.apache.druid.segment.column.ColumnHolder;
 import org.apache.druid.segment.column.ColumnType;
 import org.apache.druid.server.QueryResponse;
 import org.apache.druid.sql.calcite.parser.DruidSqlInsert;
@@ -63,14 +63,11 @@ import org.joda.time.Interval;
 import javax.annotation.Nullable;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 public class MSQTaskQueryMaker implements QueryMaker
@@ -92,6 +89,7 @@ public class MSQTaskQueryMaker implements QueryMaker
   private final ObjectMapper jsonMapper;
   private final List<Pair<Integer, String>> fieldMapping;
 
+
   MSQTaskQueryMaker(
       @Nullable final String targetDataSource,
       final OverlordClient overlordClient,
@@ -220,7 +218,7 @@ public class MSQTaskQueryMaker implements QueryMaker
 
       final List<String> segmentSortOrder = 
MultiStageQueryContext.getSortOrder(queryContext);
 
-      validateSegmentSortOrder(
+      MSQTaskQueryMakerUtils.validateSegmentSortOrder(
           segmentSortOrder,
           fieldMapping.stream().map(f -> f.right).collect(Collectors.toList())
       );
@@ -256,7 +254,7 @@ public class MSQTaskQueryMaker implements QueryMaker
     final MSQControllerTask controllerTask = new MSQControllerTask(
         taskId,
         querySpec,
-        plannerContext.getSql(),
+        MSQTaskQueryMakerUtils.maskSensitiveJsonKeys(plannerContext.getSql()),
         plannerContext.queryContextMap(),
         sqlTypeNames,
         null
@@ -283,20 +281,4 @@ public class MSQTaskQueryMaker implements QueryMaker
     return retVal;
   }
 
-  static void validateSegmentSortOrder(final List<String> sortOrder, final 
Collection<String> allOutputColumns)
-  {
-    final Set<String> allOutputColumnsSet = new HashSet<>(allOutputColumns);
-
-    for (final String column : sortOrder) {
-      if (!allOutputColumnsSet.contains(column)) {
-        throw new IAE("Column [%s] in segment sort order does not appear in 
the query output", column);
-      }
-    }
-
-    if (sortOrder.size() > 0
-        && allOutputColumns.contains(ColumnHolder.TIME_COLUMN_NAME)
-        && !ColumnHolder.TIME_COLUMN_NAME.equals(sortOrder.get(0))) {
-      throw new IAE("Segment sort order must begin with column [%s]", 
ColumnHolder.TIME_COLUMN_NAME);
-    }
-  }
 }
diff --git 
a/extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtils.java
 
b/extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtils.java
new file mode 100644
index 0000000000..3a2de0da96
--- /dev/null
+++ 
b/extensions-core/multi-stage-query/src/main/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtils.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.msq.util;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.druid.java.util.common.IAE;
+import org.apache.druid.java.util.common.StringUtils;
+import org.apache.druid.segment.column.ColumnHolder;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+public class MSQTaskQueryMakerUtils
+{
+
+  public static final Set<String> SENSISTIVE_JSON_KEYS = 
ImmutableSet.of("accessKeyId", "secretAccessKey");
+  public static final Set<Pattern> SENSITIVE_KEYS_REGEX_PATTERNS = 
SENSISTIVE_JSON_KEYS.stream()
+                                                                               
        .map(sensitiveKey ->
+                                                                               
                  Pattern.compile(
+                                                                               
                      StringUtils.format(
+                                                                               
                          
"\\\\\"%s\\\\\"(\\s)*:(\\s)*(?<sensitive>\\{(\\s)*(\\S)+?(\\s)*\\})",
+                                                                               
                          sensitiveKey
+                                                                               
                      ),
+                                                                               
                      Pattern.CASE_INSENSITIVE
+                                                                               
                  ))
+                                                                               
        .collect(Collectors.toSet());
+
+  /**
+   * This method masks the sensitive json keys that might be present in the 
SQL query matching the regex
+   * {@code key(\s)+:(\s)+{sensitive_data}}
+   * The regex pattern matches a json entry of form "key":{value} and replaces 
it with "key":\<masked\>
+   * It checks the sensitive keys for the match, greedily matches the first 
occuring brace pair ("{" and "}")
+   * into a regex group named "sensitive" and performs a string replace on the 
group. The whitespaces are accounted
+   * for in the regex.
+   */
+  public static String maskSensitiveJsonKeys(String sqlQuery)
+  {
+    StringBuilder maskedSqlQuery = new StringBuilder(sqlQuery);
+    for (Pattern p : SENSITIVE_KEYS_REGEX_PATTERNS) {
+      Matcher m = p.matcher(sqlQuery);
+      while (m.find()) {
+        String sensitiveData = m.group("sensitive");
+        int start = maskedSqlQuery.indexOf(sensitiveData);
+        int end = start + sensitiveData.length();
+        maskedSqlQuery.replace(start, end, "<masked>");
+      }
+    }
+    return maskedSqlQuery.toString();
+  }
+
+  /**
+   * Validates if each element of the sort order appears in the final output 
and if it is not empty then it starts with the
+   * __time column
+   */
+  public static void validateSegmentSortOrder(final List<String> sortOrder, 
final Collection<String> allOutputColumns)
+  {
+    final Set<String> allOutputColumnsSet = new HashSet<>(allOutputColumns);
+
+    for (final String column : sortOrder) {
+      if (!allOutputColumnsSet.contains(column)) {
+        throw new IAE("Column [%s] in segment sort order does not appear in 
the query output", column);
+      }
+    }
+
+    if (sortOrder.size() > 0
+        && allOutputColumns.contains(ColumnHolder.TIME_COLUMN_NAME)
+        && !ColumnHolder.TIME_COLUMN_NAME.equals(sortOrder.get(0))) {
+      throw new IAE("Segment sort order must begin with column [%s]", 
ColumnHolder.TIME_COLUMN_NAME);
+    }
+  }
+}
diff --git 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/sql/MSQTaskQueryMakerTest.java
 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/sql/MSQTaskQueryMakerTest.java
deleted file mode 100644
index 4bd5f94140..0000000000
--- 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/sql/MSQTaskQueryMakerTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.druid.msq.sql;
-
-import com.google.common.collect.ImmutableList;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Collections;
-
-public class MSQTaskQueryMakerTest
-{
-  @Test
-  public void testValidateSegmentSortOrder()
-  {
-    // These are all OK, so validateSegmentSortOrder does nothing.
-    MSQTaskQueryMaker.validateSegmentSortOrder(Collections.emptyList(), 
ImmutableList.of("__time", "a", "b"));
-    MSQTaskQueryMaker.validateSegmentSortOrder(ImmutableList.of("__time"), 
ImmutableList.of("__time", "a", "b"));
-    MSQTaskQueryMaker.validateSegmentSortOrder(ImmutableList.of("__time", 
"b"), ImmutableList.of("__time", "a", "b"));
-    MSQTaskQueryMaker.validateSegmentSortOrder(ImmutableList.of("b"), 
ImmutableList.of("a", "b"));
-
-    // These are not OK.
-    Assert.assertThrows(
-        IllegalArgumentException.class,
-        () -> 
MSQTaskQueryMaker.validateSegmentSortOrder(ImmutableList.of("c"), 
ImmutableList.of("a", "b"))
-    );
-
-    Assert.assertThrows(
-        IllegalArgumentException.class,
-        () -> MSQTaskQueryMaker.validateSegmentSortOrder(
-            ImmutableList.of("b", "__time"),
-            ImmutableList.of("__time", "a", "b")
-        )
-    );
-  }
-}
diff --git 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtilsTest.java
 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtilsTest.java
new file mode 100644
index 0000000000..00b76e7ef2
--- /dev/null
+++ 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtilsTest.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.msq.util;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+
+public class MSQTaskQueryMakerUtilsTest
+{
+  @Test
+  public void testValidateSegmentSortOrder()
+  {
+    // These are all OK, so validateSegmentSortOrder does nothing.
+    MSQTaskQueryMakerUtils.validateSegmentSortOrder(Collections.emptyList(), 
ImmutableList.of("__time", "a", "b"));
+    
MSQTaskQueryMakerUtils.validateSegmentSortOrder(ImmutableList.of("__time"), 
ImmutableList.of("__time", "a", "b"));
+    MSQTaskQueryMakerUtils.validateSegmentSortOrder(ImmutableList.of("__time", 
"b"), ImmutableList.of("__time", "a", "b"));
+    MSQTaskQueryMakerUtils.validateSegmentSortOrder(ImmutableList.of("b"), 
ImmutableList.of("a", "b"));
+
+    // These are not OK.
+    Assert.assertThrows(
+        IllegalArgumentException.class,
+        () -> 
MSQTaskQueryMakerUtils.validateSegmentSortOrder(ImmutableList.of("c"), 
ImmutableList.of("a", "b"))
+    );
+
+    Assert.assertThrows(
+        IllegalArgumentException.class,
+        () -> MSQTaskQueryMakerUtils.validateSegmentSortOrder(
+            ImmutableList.of("b", "__time"),
+            ImmutableList.of("__time", "a", "b")
+        )
+    );
+  }
+
+  @Test
+  public void maskSensitiveJsonKeys()
+  {
+
+    String sql1 = "\"REPLACE INTO table "
+                  + "OVERWRITE ALL\\n"
+                  + "WITH ext AS "
+                  + "(SELECT *\\nFROM TABLE(\\n  "
+                  + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"},\\\"secretAccessKey\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"}}}',\\n"
+                  + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+                  + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+                  + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  
name,\\n  country "
+                  + "FROM ext\\n"
+                  + "PARTITIONED BY DAY\"";
+
+    String sql2 = "\"REPLACE INTO table "
+                  + "OVERWRITE ALL\\n"
+                  + "WITH ext AS "
+                  + "(SELECT *\\nFROM TABLE(\\n  "
+                  + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\"
  
:{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"},\\\"secretAccessKey\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"}}}',\\n"
+                  + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+                  + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+                  + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  
name,\\n  country "
+                  + "FROM ext\\n"
+                  + "PARTITIONED BY DAY\"";
+
+    String sql3 = "\"REPLACE INTO table "
+                  + "OVERWRITE ALL\\n"
+                  + "WITH ext AS "
+                  + "(SELECT *\\nFROM TABLE(\\n  "
+                  + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":
  
{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"},\\\"secretAccessKey\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"}}}',\\n"
+                  + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+                  + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+                  + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  
name,\\n  country "
+                  + "FROM ext\\n"
+                  + "PARTITIONED BY DAY\"";
+
+    String sql4 = "\"REPLACE INTO table "
+                  + "OVERWRITE ALL\\n"
+                  + "WITH ext AS "
+                  + "(SELECT *\\nFROM TABLE(\\n  "
+                  + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":{
  
\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"},\\\"secretAccessKey\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"}}}',\\n"
+                  + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+                  + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+                  + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  
name,\\n  country "
+                  + "FROM ext\\n"
+                  + "PARTITIONED BY DAY\"";
+
+    String sql5 = "\"REPLACE INTO table "
+                  + "OVERWRITE ALL\\n"
+                  + "WITH ext AS "
+                  + "(SELECT *\\nFROM TABLE(\\n  "
+                  + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"
  
},\\\"secretAccessKey\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"}}}',\\n"
+                  + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+                  + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+                  + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  
name,\\n  country "
+                  + "FROM ext\\n"
+                  + "PARTITIONED BY DAY\"";
+
+    Assert.assertEquals(
+        "\"REPLACE INTO table "
+        + "OVERWRITE ALL\\n"
+        + "WITH ext AS "
+        + "(SELECT *\\nFROM TABLE(\\n  "
+        + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":<masked>,\\\"secretAccessKey\\\":<masked>}}',\\n"
+        + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+        + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+        + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  name,\\n  
country "
+        + "FROM ext\\n"
+        + "PARTITIONED BY DAY\"",
+        MSQTaskQueryMakerUtils.maskSensitiveJsonKeys(sql1)
+    );
+
+    Assert.assertEquals(
+        "\"REPLACE INTO table "
+        + "OVERWRITE ALL\\n"
+        + "WITH ext AS "
+        + "(SELECT *\\nFROM TABLE(\\n  "
+        + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\"
  :<masked>,\\\"secretAccessKey\\\":<masked>}}',\\n"
+        + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+        + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+        + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  name,\\n  
country "
+        + "FROM ext\\n"
+        + "PARTITIONED BY DAY\"",
+        MSQTaskQueryMakerUtils.maskSensitiveJsonKeys(sql2)
+    );
+
+    Assert.assertEquals(
+        "\"REPLACE INTO table "
+        + "OVERWRITE ALL\\n"
+        + "WITH ext AS "
+        + "(SELECT *\\nFROM TABLE(\\n  "
+        + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":
  <masked>,\\\"secretAccessKey\\\":<masked>}}',\\n"
+        + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+        + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+        + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  name,\\n  
country "
+        + "FROM ext\\n"
+        + "PARTITIONED BY DAY\"",
+        MSQTaskQueryMakerUtils.maskSensitiveJsonKeys(sql3)
+    );
+
+    Assert.assertEquals(
+        "\"REPLACE INTO table "
+        + "OVERWRITE ALL\\n"
+        + "WITH ext AS "
+        + "(SELECT *\\nFROM TABLE(\\n  "
+        + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":<masked>,\\\"secretAccessKey\\\":<masked>}}',\\n"
+        + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+        + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+        + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  name,\\n  
country "
+        + "FROM ext\\n"
+        + "PARTITIONED BY DAY\"",
+        MSQTaskQueryMakerUtils.maskSensitiveJsonKeys(sql4)
+    );
+
+    Assert.assertEquals(
+        "\"REPLACE INTO table "
+        + "OVERWRITE ALL\\n"
+        + "WITH ext AS "
+        + "(SELECT *\\nFROM TABLE(\\n  "
+        + "EXTERN(\\n    
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":<masked>,\\\"secretAccessKey\\\":<masked>}}',\\n"
+        + "'{\\\"type\\\":\\\"json\\\"}',\\n"
+        + 
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
  )\\n))\\n"
+        + "SELECT\\n  TIME_PARSE(\\\"time\\\") AS __time,\\n  name,\\n  
country "
+        + "FROM ext\\n"
+        + "PARTITIONED BY DAY\"",
+        MSQTaskQueryMakerUtils.maskSensitiveJsonKeys(sql5)
+    );
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to