use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class SqlCursorConstructor method deriveType.
// ~ Methods ----------------------------------------------------------------
public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) {
SqlSelect subSelect = call.operand(0);
validator.declareCursor(subSelect, scope);
subSelect.validateExpr(validator, scope);
return super.deriveType(validator, scope, call);
}
use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class SqlToRelConverter method convertExists.
/**
* Converts an EXISTS or IN predicate into a join. For EXISTS, the sub-query
* produces an indicator variable, and the result is a relational expression
* which outer joins that indicator to the original query. After performing
* the outer join, the condition will be TRUE if the EXISTS condition holds,
* NULL otherwise.
*
* @param seek A query, for example 'select * from emp' or
* 'values (1,2,3)' or '('Foo', 34)'.
* @param subQueryType Whether sub-query is IN, EXISTS or scalar
* @param logic Whether the answer needs to be in full 3-valued logic (TRUE,
* FALSE, UNKNOWN) will be required, or whether we can accept an
* approximation (say representing UNKNOWN as FALSE)
* @param notIn Whether the operation is NOT IN
* @return join expression
*/
private RelOptUtil.Exists convertExists(SqlNode seek, RelOptUtil.SubQueryType subQueryType, RelOptUtil.Logic logic, boolean notIn, RelDataType targetDataType) {
final SqlValidatorScope seekScope = (seek instanceof SqlSelect) ? validator.getSelectScope((SqlSelect) seek) : null;
final Blackboard seekBb = createBlackboard(seekScope, null, false);
RelNode seekRel = convertQueryOrInList(seekBb, seek, targetDataType);
return RelOptUtil.createExistsPlan(seekRel, subQueryType, logic, notIn, relBuilder);
}
use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class SqlValidatorImpl method declareCursor.
// implement SqlValidator
public void declareCursor(SqlSelect select, SqlValidatorScope parentScope) {
cursorSet.add(select);
// add the cursor to a map that maps the cursor to its select based on
// the position of the cursor relative to other cursors in that call
FunctionParamInfo funcParamInfo = functionCallStack.peek();
Map<Integer, SqlSelect> cursorMap = funcParamInfo.cursorPosToSelectMap;
int numCursors = cursorMap.size();
cursorMap.put(numCursors, select);
// create a namespace associated with the result of the select
// that is the argument to the cursor constructor; register it
// with a scope corresponding to the cursor
SelectScope cursorScope = new SelectScope(parentScope, null, select);
cursorScopes.put(select, cursorScope);
final SelectNamespace selectNs = createSelectNamespace(select, select);
String alias = deriveAlias(select, nextGeneratedId++);
registerNamespace(cursorScope, alias, selectNs, false);
}
use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class SqlValidatorImpl method validateSelectList.
protected RelDataType validateSelectList(final SqlNodeList selectItems, SqlSelect select, RelDataType targetRowType) {
// First pass, ensure that aliases are unique. "*" and "TABLE.*" items
// are ignored.
// Validate SELECT list. Expand terms of the form "*" or "TABLE.*".
final SqlValidatorScope selectScope = getSelectScope(select);
final List<SqlNode> expandedSelectItems = new ArrayList<>();
final Set<String> aliases = Sets.newHashSet();
final List<Map.Entry<String, RelDataType>> fieldList = new ArrayList<>();
for (int i = 0; i < selectItems.size(); i++) {
SqlNode selectItem = selectItems.get(i);
if (selectItem instanceof SqlSelect) {
handleScalarSubQuery(select, (SqlSelect) selectItem, expandedSelectItems, aliases, fieldList);
} else {
expandSelectItem(selectItem, select, targetRowType.isStruct() && targetRowType.getFieldCount() >= i ? targetRowType.getFieldList().get(i).getType() : unknownType, expandedSelectItems, aliases, fieldList, false);
}
}
// Create the new select list with expanded items. Pass through
// the original parser position so that any overall failures can
// still reference the original input text.
SqlNodeList newSelectList = new SqlNodeList(expandedSelectItems, selectItems.getParserPosition());
if (shouldExpandIdentifiers()) {
select.setSelectList(newSelectList);
}
getRawSelectScope(select).setExpandedSelectList(expandedSelectItems);
// TODO: when SELECT appears as a value sub-query, should be using
// something other than unknownType for targetRowType
inferUnknownTypes(targetRowType, selectScope, newSelectList);
for (SqlNode selectItem : expandedSelectItems) {
validateNoAggs(groupFinder, selectItem, "SELECT");
validateExpr(selectItem, selectScope);
}
assert fieldList.size() >= aliases.size();
return typeFactory.createStructType(fieldList);
}
use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class SqlValidatorImpl method rewriteMerge.
private void rewriteMerge(SqlMerge call) {
SqlNodeList selectList;
SqlUpdate updateStmt = call.getUpdateCall();
if (updateStmt != null) {
// if we have an update statement, just clone the select list
// from the update statement's source since it's the same as
// what we want for the select list of the merge source -- '*'
// followed by the update set expressions
selectList = SqlNode.clone(updateStmt.getSourceSelect().getSelectList());
} else {
// otherwise, just use select *
selectList = new SqlNodeList(SqlParserPos.ZERO);
selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
}
SqlNode targetTable = call.getTargetTable();
if (call.getAlias() != null) {
targetTable = SqlValidatorUtil.addAlias(targetTable, call.getAlias().getSimple());
}
// Provided there is an insert substatement, the source select for
// the merge is a left outer join between the source in the USING
// clause and the target table; otherwise, the join is just an
// inner join. Need to clone the source table reference in order
// for validation to work
SqlNode sourceTableRef = call.getSourceTableRef();
SqlInsert insertCall = call.getInsertCall();
JoinType joinType = (insertCall == null) ? JoinType.INNER : JoinType.LEFT;
final SqlNode leftJoinTerm = SqlNode.clone(sourceTableRef);
SqlNode outerJoin = new SqlJoin(SqlParserPos.ZERO, leftJoinTerm, SqlLiteral.createBoolean(false, SqlParserPos.ZERO), joinType.symbol(SqlParserPos.ZERO), targetTable, JoinConditionType.ON.symbol(SqlParserPos.ZERO), call.getCondition());
SqlSelect select = new SqlSelect(SqlParserPos.ZERO, null, selectList, outerJoin, null, null, null, null, null, null, null);
call.setSourceSelect(select);
// that via the from clause on the select
if (insertCall != null) {
SqlCall valuesCall = (SqlCall) insertCall.getSource();
SqlCall rowCall = valuesCall.operand(0);
selectList = new SqlNodeList(rowCall.getOperandList(), SqlParserPos.ZERO);
final SqlNode insertSource = SqlNode.clone(sourceTableRef);
select = new SqlSelect(SqlParserPos.ZERO, null, selectList, insertSource, null, null, null, null, null, null, null);
insertCall.setSource(select);
}
}
Aggregations