@Override protected List<QuerySource> visitRelation(Relation node, QueryState state){ if(node instanceof Join){ return node.accept(this, state); }else if( node instanceof SampledRelation){ state.addException("Sampled relations are not supported"); return null; }else if( node instanceof AliasedRelation){ AliasedRelation ar = (AliasedRelation)node; state.setKeyValue("table_alias", ar.getAlias()); List<QuerySource> relations = ar.getRelation().accept(this, state); for(QuerySource rr : relations) rr.setAlias(ar.getAlias()); return relations; }else if( node instanceof QueryBody){ return node.accept(this, state); }else{ state.addException("Unable to parse node because it has an unknown type :"+node.getClass()); return null; } }
@Override protected RelationPlan visitSampledRelation(SampledRelation node, Void context) { if (node.getColumnsToStratifyOn().isPresent()) { throw new UnsupportedOperationException("STRATIFY ON is not yet implemented"); } RelationPlan subPlan = process(node.getRelation(), context); RelationType outputDescriptor = analysis.getOutputDescriptor(node); double ratio = analysis.getSampleRatio(node); Symbol sampleWeightSymbol = null; if (node.getType() == SampledRelation.Type.POISSONIZED) { sampleWeightSymbol = symbolAllocator.newSymbol("$sampleWeight", BIGINT); } PlanNode planNode = new SampleNode(idAllocator.getNextId(), subPlan.getRoot(), ratio, SampleNode.Type.fromType(node.getType()), node.isRescaled(), Optional.ofNullable(sampleWeightSymbol)); return new RelationPlan(planNode, outputDescriptor, subPlan.getOutputSymbols(), Optional.ofNullable(sampleWeightSymbol)); }
@Override protected Void visitSampledRelation(SampledRelation node, Integer indent) { process(node.getRelation(), indent); builder.append(" TABLESAMPLE ") .append(node.getType()) .append(" (") .append(node.getSamplePercentage()) .append(')'); if (node.getColumnsToStratifyOn().isPresent()) { builder.append(" STRATIFY ON ") .append(" (") .append(Joiner.on(",").join(node.getColumnsToStratifyOn().get())); builder.append(')'); } return null; }
@Override public Node visitSampledRelation(SqlBaseParser.SampledRelationContext context) { Relation child = (Relation) visit(context.aliasedRelation()); if (context.TABLESAMPLE() == null) { return child; } Optional<List<Expression>> stratifyOn = Optional.empty(); if (context.STRATIFY() != null) { stratifyOn = Optional.of(visit(context.stratify, Expression.class)); } return new SampledRelation( getLocation(context), child, getSamplingMethod((Token) context.sampleType().getChild(0).getPayload()), (Expression) visit(context.percentage), context.RESCALED() != null, stratifyOn); }
@Override protected Void visitSampledRelation(SampledRelation node, Integer indent) { process(node.getRelation(), indent); builder.append(" TABLESAMPLE ") .append(node.getType()) .append(" (") .append(node.getSamplePercentage()) .append(')'); return null; }
public static Type fromType(SampledRelation.Type sampleType) { switch (sampleType) { case BERNOULLI: return Type.BERNOULLI; case POISSONIZED: return Type.POISSONIZED; case SYSTEM: return Type.SYSTEM; default: throw new UnsupportedOperationException("Unsupported sample type: " + sampleType); } }
private static SampledRelation.Type getSamplingMethod(Token token) { switch (token.getType()) { case SqlBaseLexer.BERNOULLI: return SampledRelation.Type.BERNOULLI; case SqlBaseLexer.SYSTEM: return SampledRelation.Type.SYSTEM; case SqlBaseLexer.POISSONIZED: return SampledRelation.Type.POISSONIZED; } throw new IllegalArgumentException("Unsupported sampling method: " + token.getText()); }
public void setSampleRatio(SampledRelation relation, double ratio) { sampleRatios.put(relation, ratio); }
public double getSampleRatio(SampledRelation relation) { Preconditions.checkState(sampleRatios.containsKey(relation), "Sample ratio missing for %s. Broken analysis?", relation); return sampleRatios.get(relation); }
@Override protected RelationType visitSampledRelation(final SampledRelation relation, AnalysisContext context) { if (relation.getColumnsToStratifyOn().isPresent()) { throw new SemanticException(NOT_SUPPORTED, relation, "STRATIFY ON is not yet implemented"); } if (!DependencyExtractor.extractNames(relation.getSamplePercentage(), analysis.getColumnReferences()).isEmpty()) { throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), "Sample percentage cannot contain column references"); } IdentityHashMap<Expression, Type> expressionTypes = getExpressionTypes(session, metadata, sqlParser, ImmutableMap.<Symbol, Type>of(), relation.getSamplePercentage()); ExpressionInterpreter samplePercentageEval = expressionOptimizer(relation.getSamplePercentage(), metadata, session, expressionTypes); Object samplePercentageObject = samplePercentageEval.optimize(symbol -> { throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), "Sample percentage cannot contain column references"); }); if (!(samplePercentageObject instanceof Number)) { throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), "Sample percentage should evaluate to a numeric expression"); } double samplePercentageValue = ((Number) samplePercentageObject).doubleValue(); if (samplePercentageValue < 0.0) { throw new SemanticException(SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE, relation.getSamplePercentage(), "Sample percentage must be greater than or equal to 0"); } else if ((samplePercentageValue > 100.0) && (relation.getType() != SampledRelation.Type.POISSONIZED || relation.isRescaled())) { throw new SemanticException(SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE, relation.getSamplePercentage(), "Sample percentage must be less than or equal to 100"); } if (relation.isRescaled() && !experimentalSyntaxEnabled) { throw new SemanticException(NOT_SUPPORTED, relation, "Rescaling is not enabled"); } RelationType descriptor = process(relation.getRelation(), context); analysis.setOutputDescriptor(relation, descriptor); analysis.setSampleRatio(relation, samplePercentageValue / 100); return descriptor; }