This is an automated email from the ASF dual-hosted git repository. xiangfu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push: new 4325cf87ec By default ignore virtual columns for select * queries in v2 (#11327) 4325cf87ec is described below commit 4325cf87ec02cb852b97becc5c28bf5535c8714e Author: Xiang Fu <xiangfu.1...@gmail.com> AuthorDate: Fri Aug 11 18:35:38 2023 -0700 By default ignore virtual columns for select * queries in v2 (#11327) --- .../org/apache/pinot/query/validate/Validator.java | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/pinot-query-planner/src/main/java/org/apache/pinot/query/validate/Validator.java b/pinot-query-planner/src/main/java/org/apache/pinot/query/validate/Validator.java index cdbe6d0999..201c645328 100644 --- a/pinot-query-planner/src/main/java/org/apache/pinot/query/validate/Validator.java +++ b/pinot-query-planner/src/main/java/org/apache/pinot/query/validate/Validator.java @@ -18,8 +18,16 @@ */ package org.apache.pinot.query.validate; +import java.util.ArrayList; +import java.util.List; import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rel.type.RelDataTypeField; +import org.apache.calcite.rel.type.RelRecordType; +import org.apache.calcite.sql.SqlIdentifier; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlNodeList; import org.apache.calcite.sql.SqlOperatorTable; +import org.apache.calcite.sql.SqlSelect; import org.apache.calcite.sql.validate.SqlConformanceEnum; import org.apache.calcite.sql.validate.SqlValidatorCatalogReader; import org.apache.calcite.sql.validate.SqlValidatorImpl; @@ -34,4 +42,85 @@ public class Validator extends SqlValidatorImpl { // TODO: support BABEL validator. Currently parser conformance is set to use BABEL. super(opTab, catalogReader, typeFactory, Config.DEFAULT.withSqlConformance(SqlConformanceEnum.LENIENT)); } + + /** + * Expand the star in the select list. + * Pinot table schema has all columns along with virtual columns. + * We don't want to include virtual columns in the select * query + * + * @param selectList Select clause to be expanded + * @param select Query + * @param includeSystemVars Whether to include system variables + * @return Expanded select list + */ + @Override + public SqlNodeList expandStar( + SqlNodeList selectList, + SqlSelect select, + boolean includeSystemVars) { + SqlNodeList expandedSelectList = super.expandStar(selectList, select, includeSystemVars); + RelRecordType validatedNodeType = (RelRecordType) getValidatedNodeType(select); + + List<String> selectedVirtualColumns = getSelectedVirtualColumns(select); + // ExpandStar will add a field for each column in the table, but we don't want to include the virtual columns + List<SqlNode> newSelectList = new ArrayList<>(); + List<RelDataTypeField> newFieldList = new ArrayList<>(); + for (int i = 0; i < expandedSelectList.size(); i++) { + SqlNode node = expandedSelectList.get(i); + if (node instanceof SqlIdentifier) { + String columnName = getColumnName((SqlIdentifier) node); + if (isVirtualColumn(columnName)) { + // If the virtual column is selected, remove it from the list of selected virtual columns + if (!selectedVirtualColumns.remove(columnName)) { + continue; + } + } + } + newSelectList.add(node); + newFieldList.add(validatedNodeType.getFieldList().get(i)); + } + // Ensure the validation node type is updated + setValidatedNodeType(select, new RelRecordType(newFieldList)); + return new SqlNodeList(newSelectList, selectList.getParserPosition()); + } + + /** + * Get the all the virtual columns explicitly selected from the query selection list. + * Use list in case there are duplicates. + * + * @param select query + * @return list of virtual columns selected + */ + private List<String> getSelectedVirtualColumns(SqlSelect select) { + List<String> columnNamesFromSelectList = new ArrayList<>(); + for (SqlNode node : select.getSelectList().getList()) { + if (node instanceof SqlIdentifier) { + String columnName = getColumnName((SqlIdentifier) node); + if (isVirtualColumn(columnName)) { + columnNamesFromSelectList.add(columnName); + } + } + } + return columnNamesFromSelectList; + } + + /** + * Check if the column is a virtual column. + * @param columnName column name + * @return true if the column is a virtual column + */ + private static boolean isVirtualColumn(String columnName) { + return columnName.length() > 0 && columnName.charAt(0) == '$'; + } + + /** + * Extract the column name from the identifier. The identifier could be in the format of [table].[columnName] or + * just [columnName]. + * @param identifier column identifier + * @return column name + */ + private static String getColumnName(SqlIdentifier identifier) { + List<String> names = identifier.names; + return names.get(names.size() - 1); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org