Skip to content

Commit

Permalink
[CALCITE-1581] UDTF like in hive
Browse files Browse the repository at this point in the history
remove unused empty line

remove test code  & add comment

add comment

check for more than one table function in select

fix test sql

make _table_function_ as a constant

support table function without from

add comment

fix conflict

move rewrite to SqlToRelConverter

fix code style

modify comment

fix doc issue

remove used blank

add more test case

fix format

fix some format issue

fix compile failture

fix compile error

use SqlUtil#newContextException

format code
  • Loading branch information
pengzhiwei committed Nov 29, 2019
1 parent ca27fe9 commit 7d1a5bc
Show file tree
Hide file tree
Showing 20 changed files with 571 additions and 12 deletions.
32 changes: 27 additions & 5 deletions core/src/main/codegen/templates/Parser.jj
Original file line number Diff line number Diff line change
Expand Up @@ -1728,15 +1728,37 @@ List<SqlNode> SelectList() :
SqlNode SelectItem() :
{
SqlNode e;
final SqlIdentifier id;
SqlIdentifier id;
final List<SqlNode> ids = new ArrayList();
final Span s = span();
}
{
e = SelectExpression()
[
[ <AS> ]
id = SimpleIdentifier() {
e = SqlStdOperatorTable.AS.createCall(span().end(e), e, id);
}
(
LOOKAHEAD(2) (
[ <AS> ]
id = SimpleIdentifier()
{
e = SqlStdOperatorTable.AS.createCall(s.end(e), e, id);
}
)
|
(
<AS> <LPAREN>
id = SimpleIdentifier() {
ids.add(id);
}
( <COMMA> id = SimpleIdentifier() { ids.add(id);} )*
<RPAREN> {
if (!this.conformance.allowSelectTableFunction()) {
throw SqlUtil.newContextException(getPos(),
RESOURCE.notAllowTableFunctionInSelect());
}
e = SqlStdOperatorTable.AS.createCall(s.end(e), e, new SqlNodeList(ids, s.end(e)));
}
)
)
]
{
return e;
Expand Down
12 changes: 12 additions & 0 deletions core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,18 @@ ExInst<CalciteException> invalidTypesForComparison(String clazzName0, String op,

@BaseMessage("Not a valid input for REGEXP_REPLACE: ''{0}''")
ExInst<CalciteException> invalidInputForRegexpReplace(String value);

@BaseMessage("Table function is not allowed in select list in current SQL conformance level")
ExInst<SqlValidatorException> notAllowTableFunctionInSelect();

@BaseMessage("''{0}'' should be a table function")
ExInst<SqlValidatorException> exceptTableFunction(String name);

@BaseMessage("Only one table function is allowed in select list")
ExInst<SqlValidatorException> onlyOneTableFunctionAllowedInSelect();

@BaseMessage("Table function is not allowed in aggregate statement")
ExInst<SqlValidatorException> notAllowTableFunctionInAggregate();
}

// End CalciteResource.java
25 changes: 20 additions & 5 deletions core/src/main/java/org/apache/calcite/sql/SqlAsOperator.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.calcite.util.Util;

import java.util.ArrayList;
import java.util.List;

import static org.apache.calcite.util.Static.RESOURCE;
Expand Down Expand Up @@ -102,12 +103,26 @@ public void validateCall(
// we don't want to validate the identifier.
final List<SqlNode> operands = call.getOperandList();
assert operands.size() == 2;
assert operands.get(1) instanceof SqlIdentifier;
operands.get(0).validateExpr(validator, scope);
SqlIdentifier id = (SqlIdentifier) operands.get(1);
if (!id.isSimple()) {
throw validator.newValidationError(id,
RESOURCE.aliasMustBeSimpleIdentifier());

SqlNode asIdentifier = operands.get(1);
assert asIdentifier instanceof SqlIdentifier
|| (asIdentifier instanceof SqlNodeList
&& validator.getConformance().allowSelectTableFunction());

List<SqlNode> ids = new ArrayList<>();
if (asIdentifier instanceof SqlIdentifier) {
ids.add(operands.get(1));
} else {
ids.addAll(((SqlNodeList) operands.get(1)).getList());
}
for (int i = 0; i < ids.size(); i++) {
assert ids.get(i) instanceof SqlIdentifier;
SqlIdentifier id = (SqlIdentifier) ids.get(i);
if (!id.isSimple()) {
throw validator.newValidationError(id,
RESOURCE.aliasMustBeSimpleIdentifier());
}
}
}

Expand Down
15 changes: 15 additions & 0 deletions core/src/main/java/org/apache/calcite/sql/SqlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,21 @@ private void visitChild(SqlNode node) {
return check(type);
}
}

/**
* Whether the selectItem is a table function node in the select.
* eg. "select table_func(1) as (f0,f1)"
*
* @param selectItem select item
* @return true if this selectItem is a table function call
*/
public static boolean isTableFunctionInSelect(SqlNode selectItem) {
if (selectItem.getKind() == SqlKind.AS) {
SqlBasicCall call = (SqlBasicCall) selectItem;
return call.getOperands()[1] instanceof SqlNodeList;
}
return false;
}
}

// End SqlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlUtil;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.util.Util;
Expand Down Expand Up @@ -69,7 +70,12 @@ protected RelDataType validateImpl(RelDataType targetRowType) {
final SqlValidatorNamespace childNs =
validator.getNamespace(operands.get(0));
final RelDataType rowType = childNs.getRowTypeSansSystemColumns();
final List<SqlNode> columnNames = Util.skip(operands, 2);
List<SqlNode> columnNames;
if (SqlUtil.isTableFunctionInSelect(call)) {
columnNames = ((SqlNodeList) operands.get(1)).getList();
} else {
columnNames = Util.skip(operands, 2);
}
for (final SqlNode operand : columnNames) {
String name = ((SqlIdentifier) operand).getSimple();
if (nameList.contains(name)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public boolean allowExtendedTrim() {
public boolean allowPluralTimeUnits() {
return SqlConformanceEnum.DEFAULT.allowPluralTimeUnits();
}

public boolean allowSelectTableFunction() {
return SqlConformanceEnum.DEFAULT.allowSelectTableFunction();
}
}

// End SqlAbstractConformance.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public interface SqlConformance {
@Deprecated // to be removed before 2.0
SqlConformanceEnum PRAGMATIC_2003 = SqlConformanceEnum.PRAGMATIC_2003;

SqlConformanceEnum HIVE = SqlConformanceEnum.HIVE;
/**
* Whether this dialect supports features from a wide variety of
* dialects. This is enabled for the Babel parser, disabled otherwise.
Expand Down Expand Up @@ -408,6 +409,13 @@ public interface SqlConformance {
* false otherwise.
*/
boolean allowPluralTimeUnits();

/**
* Whether SELECT can contain a table function.
* <p>For example, consider the query
* <blockquote><pre> SELECT SPLIT(col) AS (F0, F1) FROM A </pre> </blockquote>
*/
boolean allowSelectTableFunction();
}

// End SqlConformance.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ public enum SqlConformanceEnum implements SqlConformance {

/** Conformance value that instructs Calcite to use SQL semantics
* consistent with Microsoft SQL Server version 2008. */
SQL_SERVER_2008;
SQL_SERVER_2008,

/** Conformance value that instructs Calcite to use SQL semantics
* consistent with Hive version. */
HIVE;

public boolean isLiberal() {
switch (this) {
Expand Down Expand Up @@ -314,6 +318,14 @@ public boolean allowExtendedTrim() {
}
}

public boolean allowSelectTableFunction() {
switch (this) {
case HIVE:
return true;
default:
return false;
}
}
}

// End SqlConformanceEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ protected SqlDelegatingConformance(SqlConformance delegate) {
return delegate.allowNiladicParentheses();
}

@Override public boolean allowSelectTableFunction() {
return delegate.allowSelectTableFunction();
}
}

// End SqlDelegatingConformance.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.calcite.runtime.CalciteContextException;
import org.apache.calcite.runtime.CalciteException;
import org.apache.calcite.runtime.Resources;
import org.apache.calcite.sql.SqlBasicCall;
import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlDataTypeSpec;
import org.apache.calcite.sql.SqlDelete;
Expand Down Expand Up @@ -749,6 +750,14 @@ CalciteException handleUnresolvedFunction(SqlCall call,
*/
SqlValidatorScope getOverScope(SqlNode node);

/**
* Returns the table function SqlBasicCall in SqlSelect.
*
* @param select The select node
* @return The table function node associate with the select node
*/
SqlBasicCall getTableFunctionInSelect(SqlSelect select);

/**
* Validates that a query is capable of producing a return of given modality
* (relational or streaming).
Expand Down
Loading

0 comments on commit 7d1a5bc

Please sign in to comment.