Skip to content

Commit

Permalink
Implement SQL validation based on grammar element
Browse files Browse the repository at this point in the history
Signed-off-by: Tomoyuki Morita <[email protected]>
  • Loading branch information
ykmr1224 committed Sep 17, 2024
1 parent c22929b commit d84304f
Show file tree
Hide file tree
Showing 6 changed files with 982 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.spark.validator;

import java.util.Set;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class DenyListGrammarElementValidator implements GrammarElementValidator {
private final Set<GrammarElement> denyList;

@Override
public boolean isValid(GrammarElement element) {
return !denyList.contains(element);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.spark.validator;

import lombok.AllArgsConstructor;

@AllArgsConstructor
enum GrammarElement {
ALTER_NAMESPACE("ALTER DATABASE/TABLE/NAMESPACE"),
ALTER_VIEW("ALTER VIEW"),
CREATE_NAMESPACE("CREATE DATABASE/TABLE/NAMESPACE"),
CREATE_FUNCTION("CREATE FUNCTION"),
CREATE_VIEW("CREATE VIEW"),
DROP_NAMESPACE("DROP DATABASE/TABLE/NAMESPACE"),
DROP_FUNCTION("DROP FUNCTION"),
DROP_VIEW("DROP VIEW"),
DROP_TABLE("DROP TABLE"),
REPAIR_TABLE("REPAIR TABLE"), // does this conflict with DROP_NAMESPACE?
TRUNCATE_TABLE("TRUNCATE TABLE"),
// DML Statements
INSERT("INSERT"),
LOAD("LOAD"),

// Data Retrieval Statements
EXPLAIN("EXPLAIN"),
WITH("WITH"),
CLUSTER_BY("CLUSTER BY"),
DISTRIBUTE_BY("DISTRIBUTE BY"),
GROUP_BY("GROUP BY"),
HAVING("HAVING"),
HINTS("HINTS"),
INLINE_TABLE("Inline Table(VALUES)"),
INNER_JOIN("INNER JOIN"),
CROSS_JOIN("CROSS JOIN"),
LEFT_OUTER_JOIN("LEFT OUTER JOIN"),
LEFT_SEMI_JOIN("LEFT SEMI JOIN"),
RIGHT_OUTER_JOIN("RIGHT OUTER JOIN"),
FULL_OUTER_JOIN("FULL OUTER JOIN"),
LEFT_ANTI_JOIN("LEFT ANTI JOIN"),
TABLESAMPLE("TABLESAMPLE"),
TABLE_VALUED_FUNCTION("Table-valued function"),
LATERAL_VIEW("LATERAL VIEW"),
LATERAL_SUBQUERY("LATERAL SUBQUERY"),
TRANSFORM("TRANSFORM"),

// Auxiliary Statements
MANAGE_RESOURCE("Resource management statements"),
ANALYZE_TABLE("ANALYZE TABLE(S)"),
CACHE_TABLE("CACHE TABLE"),
CLEAR_CACHE("CLEAR CACHE"),
DESCRIBE_NAMESPACE("DESCRIBE (NAMESPACE|DATABASE|SCHEMA"),
DESCRIBE_FUNCTION("DESCRIBE FUNCTION"),
DESCRIBE_QUERY("DESCRIBE QUERY"),
DESCRIBE_TABLE("DESCRIBE TABLE"),
REFRESH_RESOURCE("REFRESH"),
REFRESH_TABLE("REFRESH TABLE"),
REFRESH_FUNCTION("REFRESH FUNCTION"),
RESET("RESET"),
SET("SET"),
SHOW_COLUMNS("SHOW COLUMNS"),
SHOW_CREATE_TABLE("SHOW CREATE TABLE"),
SHOW_NAMESPACES("SHOW (DATABASES|SCHEMAS)"),
SHOW_FUNCTIONS("SHOW FUNCTIONS"),
SHOW_PARTITIONS("SHOW PARTITIONS"),
SHOW_TABLE_EXTENDED("SHOW TABLE EXTENDED"),
SHOW_TABLES("SHOW TABLES"),
SHOW_TBLPROPERTIES("SHOW TBLPROPERTIES"),
SHOW_VIEWS("SHOW VIEWS"),
UNCACHE_TABLE("UNCACHE TABLE"),

// Functions
MAP_FUNCTIONS("Map functions"),
CSV_FUNCTIONS("CSV functions"),
MISC_FUNCTIONS("Misc functions"),

SELECT("SELECT");

String description;

@Override
public String toString() {
return description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.spark.validator;

public interface GrammarElementValidator {
boolean isValid(GrammarElement element);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.spark.validator;

import static org.opensearch.sql.spark.validator.GrammarElement.*;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Map;
import java.util.Set;
import org.opensearch.sql.datasource.model.DataSourceType;

public class GrammarElementValidatorFactory {
private static final Set<GrammarElement> DEFAULT_DENY_LIST =
ImmutableSet.of(CREATE_FUNCTION, DROP_FUNCTION, INSERT, LOAD, HINTS, TABLESAMPLE);

private static final Set<GrammarElement> CWL_DENY_LIST =
copyBuilder(DEFAULT_DENY_LIST)
.add(
ALTER_NAMESPACE,
ALTER_VIEW,
CREATE_NAMESPACE,
CREATE_VIEW,
DROP_NAMESPACE,
DROP_VIEW,
REPAIR_TABLE,
TRUNCATE_TABLE)
.build();

private static final Set<GrammarElement> S3GLUE_DENY_LIST =
copyBuilder(DEFAULT_DENY_LIST)
.add(
ALTER_VIEW,
CREATE_VIEW,
DROP_VIEW,
REPAIR_TABLE,
DISTRIBUTE_BY,
INLINE_TABLE,
TRUNCATE_TABLE,
CLUSTER_BY,
DISTRIBUTE_BY,
CROSS_JOIN,
LEFT_SEMI_JOIN,
RIGHT_OUTER_JOIN,
FULL_OUTER_JOIN,
LEFT_ANTI_JOIN,
TABLESAMPLE,
TABLE_VALUED_FUNCTION,
TRANSFORM,
MANAGE_RESOURCE,
DESCRIBE_FUNCTION,
REFRESH_RESOURCE,
REFRESH_FUNCTION,
RESET,
SET,
SHOW_FUNCTIONS,
SHOW_VIEWS,
MISC_FUNCTIONS)
.build();

private static Map<DataSourceType, GrammarElementValidator> validatorMap =
ImmutableMap.of(DataSourceType.S3GLUE, new DenyListGrammarElementValidator(S3GLUE_DENY_LIST));

public GrammarElementValidator getValidatorForDatasource(DataSourceType dataSourceType) {
return validatorMap.get(dataSourceType);
}

private static ImmutableSet.Builder<GrammarElement> copyBuilder(Set<GrammarElement> original) {
return ImmutableSet.<GrammarElement>builder().addAll(original);
}
}
Loading

0 comments on commit d84304f

Please sign in to comment.