use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class CassandraSchema method addMaterializedViews.
/**
* Add all materialized views defined in the schema to this column family
*/
private void addMaterializedViews() {
// Close the hook use to get us here
hook.close();
for (MaterializedViewMetadata view : getKeyspace().getMaterializedViews()) {
String tableName = view.getBaseTable().getName();
StringBuilder queryBuilder = new StringBuilder("SELECT ");
// Add all the selected columns to the query
List<String> columnNames = new ArrayList<String>();
for (ColumnMetadata column : view.getColumns()) {
columnNames.add("\"" + column.getName() + "\"");
}
queryBuilder.append(Util.toString(columnNames, "", ", ", ""));
queryBuilder.append(" FROM \"" + tableName + "\"");
// Get the where clause from the system schema
String whereQuery = "SELECT where_clause from system_schema.views " + "WHERE keyspace_name='" + keyspace + "' AND view_name='" + view.getName() + "'";
queryBuilder.append(" WHERE " + session.execute(whereQuery).one().getString(0));
// Parse and unparse the view query to get properly quoted field names
String query = queryBuilder.toString();
SqlParser.ConfigBuilder configBuilder = SqlParser.configBuilder();
configBuilder.setUnquotedCasing(Casing.UNCHANGED);
SqlSelect parsedQuery;
try {
parsedQuery = (SqlSelect) SqlParser.create(query, configBuilder.build()).parseQuery();
} catch (SqlParseException e) {
LOGGER.warn("Could not parse query {} for CQL view {}.{}", query, keyspace, view.getName());
continue;
}
StringWriter stringWriter = new StringWriter(query.length());
PrintWriter printWriter = new PrintWriter(stringWriter);
SqlWriter writer = new SqlPrettyWriter(CalciteSqlDialect.DEFAULT, true, printWriter);
parsedQuery.unparse(writer, 0, 0);
query = stringWriter.toString();
// Add the view for this query
String viewName = "$" + getTableNames().size();
SchemaPlus schema = parentSchema.getSubSchema(name);
CalciteSchema calciteSchema = CalciteSchema.from(schema);
List<String> viewPath = calciteSchema.path(viewName);
schema.add(viewName, MaterializedViewTable.create(calciteSchema, query, null, viewPath, view.getName(), true));
}
}
use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class SqlTesterImpl method getMonotonicity.
public SqlMonotonicity getMonotonicity(String sql) {
final SqlValidator validator = getValidator();
final SqlNode node = parseAndValidate(validator, sql);
final SqlSelect select = (SqlSelect) node;
final SqlNode selectItem0 = select.getSelectList().get(0);
final SqlValidatorScope scope = validator.getSelectScope(select);
return selectItem0.getMonotonicity(scope);
}
use of org.apache.calcite.sql.SqlSelect in project calcite by apache.
the class AggChecker method visit.
public Void visit(SqlCall call) {
final SqlValidatorScope scope = scopes.peek();
if (call.getOperator().isAggregator()) {
if (distinct) {
if (scope instanceof AggregatingSelectScope) {
SqlNodeList selectList = ((SqlSelect) scope.getNode()).getSelectList();
// Check if this aggregation function is just an element in the select
for (SqlNode sqlNode : selectList) {
if (sqlNode.getKind() == SqlKind.AS) {
sqlNode = ((SqlCall) sqlNode).operand(0);
}
if (validator.expand(sqlNode, scope).equalsDeep(call, Litmus.IGNORE)) {
return null;
}
}
}
// Cannot use agg fun in ORDER BY clause if have SELECT DISTINCT.
SqlNode originalExpr = validator.getOriginal(call);
final String exprString = originalExpr.toString();
throw validator.newValidationError(call, RESOURCE.notSelectDistinctExpr(exprString));
}
// BY deptno'
return null;
}
if (call.getKind() == SqlKind.FILTER) {
call.operand(0).accept(this);
return null;
}
// Visit the operand in window function
if (call.getKind() == SqlKind.OVER) {
for (SqlNode operand : call.<SqlCall>operand(0).getOperandList()) {
operand.accept(this);
}
// Check the OVER clause
final SqlNode over = call.operand(1);
if (over instanceof SqlCall) {
over.accept(this);
} else if (over instanceof SqlIdentifier) {
// Check the corresponding SqlWindow in WINDOW clause
final SqlWindow window = scope.lookupWindow(((SqlIdentifier) over).getSimple());
window.getPartitionList().accept(this);
window.getOrderList().accept(this);
}
}
if (isGroupExpr(call)) {
// This call matches an expression in the GROUP BY clause.
return null;
}
final SqlCall groupCall = SqlStdOperatorTable.convertAuxiliaryToGroupCall(call);
if (groupCall != null) {
if (isGroupExpr(groupCall)) {
// TUMBLE(rowtime, INTERVAL '1' HOUR')
return null;
}
throw validator.newValidationError(groupCall, RESOURCE.auxiliaryWithoutMatchingGroupCall(call.getOperator().getName(), groupCall.getOperator().getName()));
}
if (call.isA(SqlKind.QUERY)) {
// references to forbidden columns.
return null;
}
// Switch to new scope.
SqlValidatorScope newScope = scope.getOperandScope(call);
scopes.push(newScope);
// Visit the operands (only expressions).
call.getOperator().acceptCall(this, call, true, ArgHandlerImpl.<Void>instance());
// Restore scope.
scopes.pop();
return null;
}
use of org.apache.calcite.sql.SqlSelect in project flink by apache.
the class SqlValidatorImpl method performUnconditionalRewrites.
/**
* Performs expression rewrites which are always used unconditionally. These rewrites massage
* the expression tree into a standard form so that the rest of the validation logic can be
* simpler.
*
* @param node expression to be rewritten
* @param underFrom whether node appears directly under a FROM clause
* @return rewritten expression
*/
protected SqlNode performUnconditionalRewrites(SqlNode node, boolean underFrom) {
if (node == null) {
return null;
}
SqlNode newOperand;
// first transform operands and invoke generic call rewrite
if (node instanceof SqlCall) {
if (node instanceof SqlMerge) {
validatingSqlMerge = true;
}
SqlCall call = (SqlCall) node;
final SqlKind kind = call.getKind();
final List<SqlNode> operands = call.getOperandList();
for (int i = 0; i < operands.size(); i++) {
SqlNode operand = operands.get(i);
boolean childUnderFrom;
if (kind == SqlKind.SELECT) {
childUnderFrom = i == SqlSelect.FROM_OPERAND;
} else if (kind == SqlKind.AS && (i == 0)) {
// for an aliased expression, it is under FROM if
// the AS expression is under FROM
childUnderFrom = underFrom;
} else {
childUnderFrom = false;
}
newOperand = performUnconditionalRewrites(operand, childUnderFrom);
if (newOperand != null && newOperand != operand) {
call.setOperand(i, newOperand);
}
}
if (call.getOperator() instanceof SqlUnresolvedFunction) {
assert call instanceof SqlBasicCall;
final SqlUnresolvedFunction function = (SqlUnresolvedFunction) call.getOperator();
// This function hasn't been resolved yet. Perform
// a half-hearted resolution now in case it's a
// builtin function requiring special casing. If it's
// not, we'll handle it later during overload resolution.
final List<SqlOperator> overloads = new ArrayList<>();
opTab.lookupOperatorOverloads(function.getNameAsId(), function.getFunctionType(), SqlSyntax.FUNCTION, overloads, catalogReader.nameMatcher());
if (overloads.size() == 1) {
((SqlBasicCall) call).setOperator(overloads.get(0));
}
}
if (config.callRewrite()) {
node = call.getOperator().rewriteCall(this, call);
}
} else if (node instanceof SqlNodeList) {
SqlNodeList list = (SqlNodeList) node;
for (int i = 0, count = list.size(); i < count; i++) {
SqlNode operand = list.get(i);
newOperand = performUnconditionalRewrites(operand, false);
if (newOperand != null) {
list.getList().set(i, newOperand);
}
}
}
// now transform node itself
final SqlKind kind = node.getKind();
switch(kind) {
case VALUES:
// CHECKSTYLE: IGNORE 1
if (underFrom || true) {
// over and over
return node;
} else {
final SqlNodeList selectList = new SqlNodeList(SqlParserPos.ZERO);
selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
return new SqlSelect(node.getParserPosition(), null, selectList, node, null, null, null, null, null, null, null, null);
}
case ORDER_BY:
{
SqlOrderBy orderBy = (SqlOrderBy) node;
handleOffsetFetch(orderBy.offset, orderBy.fetch);
if (orderBy.query instanceof SqlSelect) {
SqlSelect select = (SqlSelect) orderBy.query;
// an order-sensitive function like RANK.
if (select.getOrderList() == null) {
// push ORDER BY into existing select
select.setOrderBy(orderBy.orderList);
select.setOffset(orderBy.offset);
select.setFetch(orderBy.fetch);
return select;
}
}
if (orderBy.query instanceof SqlWith && ((SqlWith) orderBy.query).body instanceof SqlSelect) {
SqlWith with = (SqlWith) orderBy.query;
SqlSelect select = (SqlSelect) with.body;
// an order-sensitive function like RANK.
if (select.getOrderList() == null) {
// push ORDER BY into existing select
select.setOrderBy(orderBy.orderList);
select.setOffset(orderBy.offset);
select.setFetch(orderBy.fetch);
return with;
}
}
final SqlNodeList selectList = new SqlNodeList(SqlParserPos.ZERO);
selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
final SqlNodeList orderList;
if (getInnerSelect(node) != null && isAggregate(getInnerSelect(node))) {
orderList = SqlNode.clone(orderBy.orderList);
// We assume that ORDER BY item is present in SELECT list.
for (int i = 0; i < orderList.size(); i++) {
SqlNode sqlNode = orderList.get(i);
SqlNodeList selectList2 = getInnerSelect(node).getSelectList();
for (Ord<SqlNode> sel : Ord.zip(selectList2)) {
if (stripAs(sel.e).equalsDeep(sqlNode, Litmus.IGNORE)) {
orderList.set(i, SqlLiteral.createExactNumeric(Integer.toString(sel.i + 1), SqlParserPos.ZERO));
}
}
}
} else {
orderList = orderBy.orderList;
}
return new SqlSelect(SqlParserPos.ZERO, null, selectList, orderBy.query, null, null, null, null, orderList, orderBy.offset, orderBy.fetch, null);
}
case EXPLICIT_TABLE:
{
// (TABLE t) is equivalent to (SELECT * FROM t)
SqlCall call = (SqlCall) node;
final SqlNodeList selectList = new SqlNodeList(SqlParserPos.ZERO);
selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
return new SqlSelect(SqlParserPos.ZERO, null, selectList, call.operand(0), null, null, null, null, null, null, null, null);
}
case DELETE:
{
SqlDelete call = (SqlDelete) node;
SqlSelect select = createSourceSelectForDelete(call);
call.setSourceSelect(select);
break;
}
case UPDATE:
{
SqlUpdate call = (SqlUpdate) node;
SqlSelect select = createSourceSelectForUpdate(call);
call.setSourceSelect(select);
// in which case leave it alone).
if (!validatingSqlMerge) {
SqlNode selfJoinSrcExpr = getSelfJoinExprForUpdate(call.getTargetTable(), UPDATE_SRC_ALIAS);
if (selfJoinSrcExpr != null) {
node = rewriteUpdateToMerge(call, selfJoinSrcExpr);
}
}
break;
}
case MERGE:
{
SqlMerge call = (SqlMerge) node;
rewriteMerge(call);
break;
}
}
return node;
}
use of org.apache.calcite.sql.SqlSelect in project flink by apache.
the class SqlValidatorImpl method validateDelete.
public void validateDelete(SqlDelete call) {
final SqlSelect sqlSelect = call.getSourceSelect();
validateSelect(sqlSelect, unknownType);
final SqlValidatorNamespace targetNamespace = getNamespace(call);
validateNamespace(targetNamespace, unknownType);
final SqlValidatorTable table = targetNamespace.getTable();
validateAccess(call.getTargetTable(), table, SqlAccessEnum.DELETE);
}
Aggregations