@Override protected Void visitSelect(Select node, Integer indent) { append(indent, "SELECT"); if (node.isDistinct()) { builder.append(" DISTINCT"); } if (node.getSelectItems().size() > 1) { boolean first = true; for (SelectItem item : node.getSelectItems()) { builder.append("\n") .append(indentString(indent)) .append(first ? " " : ", "); process(item, indent); first = false; } } else { builder.append(' '); process(getOnlyElement(node.getSelectItems()), indent); } builder.append('\n'); return null; }
@Override protected Object visitSelectItem(SelectItem node, QueryState state){ if(node instanceof SingleColumn){ SingleColumn sc = (SingleColumn)node; Column column = (Column)sc.getExpression().accept(this, state); if(column != null){ String alias = null; if(sc.getAlias().isPresent()) alias = sc.getAlias().get(); column.setAlias(alias); Column col2 = state.getHeading().getColumnByNameAndOp(column.getColumn(), column.getOp()); if(col2 != null){ if(!col2.isVisible()) { state.getHeading().remove(col2); } if(col2.getAlias() != null && alias != null && !col2.getAlias().equals(alias)){ state.getHeading().add(column); }else { state.getHeading().add(column); if(col2.getAlias() == null) col2.setAlias(alias); col2.setVisible(true); col2.setIndex(column.getIndex()); } }else{ state.getHeading().add(column); } } }else{ state.getHeading().add(createColumn(node.toString(), null, state, "select.+", ".+from")); } return true; }
private RelationType computeOutputDescriptor(QuerySpecification node, RelationType inputTupleDescriptor) { ImmutableList.Builder<Field> outputFields = ImmutableList.builder(); for (SelectItem item : node.getSelect().getSelectItems()) { if (item instanceof AllColumns) { // expand * and T.* Optional<QualifiedName> starPrefix = ((AllColumns) item).getPrefix(); for (Field field : inputTupleDescriptor.resolveFieldsWithPrefix(starPrefix)) { outputFields.add(Field.newUnqualified(field.getName(), field.getType())); } } else if (item instanceof SingleColumn) { SingleColumn column = (SingleColumn) item; Expression expression = column.getExpression(); Optional<String> alias = column.getAlias(); if (!alias.isPresent()) { QualifiedName name = null; if (expression instanceof QualifiedNameReference) { name = ((QualifiedNameReference) expression).getName(); } else if (expression instanceof DereferenceExpression) { name = DereferenceExpression.getQualifiedName((DereferenceExpression) expression); } if (name != null) { alias = Optional.of(getLast(name.getOriginalParts())); } } outputFields.add(Field.newUnqualified(alias, analysis.getType(expression))); // TODO don't use analysis as a side-channel. Use outputExpressions to look up the type } else { throw new IllegalArgumentException("Unsupported SelectItem type: " + item.getClass().getName()); } } return new RelationType(outputFields.build()); }
public static Select selectList(Expression... expressions) { ImmutableList.Builder<SelectItem> items = ImmutableList.builder(); for (Expression expression : expressions) { items.add(new SingleColumn(expression)); } return new Select(false, items.build()); }
private List<FieldOrExpression> analyzeSelect(QuerySpecification node, RelationType tupleDescriptor, AnalysisContext context) { ImmutableList.Builder<FieldOrExpression> outputExpressionBuilder = ImmutableList.builder(); for (SelectItem item : node.getSelect().getSelectItems()) { if (item instanceof AllColumns) { // expand * and T.* Optional<QualifiedName> starPrefix = ((AllColumns) item).getPrefix(); List<Field> fields = tupleDescriptor.resolveFieldsWithPrefix(starPrefix); if (fields.isEmpty()) { if (starPrefix.isPresent()) { throw new SemanticException(MISSING_TABLE, item, "Table '%s' not found", starPrefix.get()); } else { throw new SemanticException(WILDCARD_WITHOUT_FROM, item, "SELECT * not allowed in queries without FROM clause"); } } for (Field field : fields) { int fieldIndex = tupleDescriptor.indexOf(field); outputExpressionBuilder.add(new FieldOrExpression(fieldIndex)); if (node.getSelect().isDistinct() && !field.getType().isComparable()) { throw new SemanticException(TYPE_MISMATCH, node.getSelect(), "DISTINCT can only be applied to comparable types (actual: %s)", field.getType()); } } } else if (item instanceof SingleColumn) { SingleColumn column = (SingleColumn) item; ExpressionAnalysis expressionAnalysis = analyzeExpression(column.getExpression(), tupleDescriptor, context); analysis.recordSubqueries(node, expressionAnalysis); outputExpressionBuilder.add(new FieldOrExpression(column.getExpression())); Type type = expressionAnalysis.getType(column.getExpression()); if (node.getSelect().isDistinct() && !type.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node.getSelect(), "DISTINCT can only be applied to comparable types (actual: %s): %s", type, column.getExpression()); } } else { throw new IllegalArgumentException("Unsupported SelectItem type: " + item.getClass().getName()); } } ImmutableList<FieldOrExpression> result = outputExpressionBuilder.build(); analysis.setOutputExpressions(node, result); return result; }
public static SelectItem unaliasedName(String name) { return new SingleColumn(nameReference(name)); }
public static SelectItem aliasedName(String name, String alias) { return new SingleColumn(nameReference(name), alias); }
public static Select selectList(SelectItem... items) { return new Select(false, ImmutableList.copyOf(items)); }
public static Select selectAll(List<SelectItem> items) { return new Select(false, items); }
public static SelectItem aliasedNullToEmpty(String column, String alias) { return new SingleColumn(new CoalesceExpression(nameReference(column), new StringLiteral("")), alias); }