Search in sources :

Example 11 with ValidationException

use of org.apache.calcite.tools.ValidationException in project druid by apache.

the class DruidPlanner method validateAndGetDataSourceForInsert.

/**
 * Extract target datasource from a {@link SqlInsert}, and also validate that the INSERT is of a form we support.
 * Expects the INSERT target to be either an unqualified name, or a name qualified by the default schema.
 */
private String validateAndGetDataSourceForInsert(final SqlInsert insert) throws ValidationException {
    if (insert.isUpsert()) {
        throw new ValidationException("UPSERT is not supported.");
    }
    if (insert.getTargetColumnList() != null) {
        throw new ValidationException("INSERT with target column list is not supported.");
    }
    final SqlIdentifier tableIdentifier = (SqlIdentifier) insert.getTargetTable();
    final String dataSource;
    if (tableIdentifier.names.isEmpty()) {
        // I don't think this can happen, but include a branch for it just in case.
        throw new ValidationException("INSERT requires target table.");
    } else if (tableIdentifier.names.size() == 1) {
        // Unqualified name.
        dataSource = Iterables.getOnlyElement(tableIdentifier.names);
    } else {
        // Qualified name.
        final String defaultSchemaName = Iterables.getOnlyElement(CalciteSchema.from(frameworkConfig.getDefaultSchema()).path(null));
        if (tableIdentifier.names.size() == 2 && defaultSchemaName.equals(tableIdentifier.names.get(0))) {
            dataSource = tableIdentifier.names.get(1);
        } else {
            throw new ValidationException(StringUtils.format("Cannot INSERT into [%s] because it is not a Druid datasource.", tableIdentifier));
        }
    }
    try {
        IdUtils.validateId("INSERT dataSource", dataSource);
    } catch (IllegalArgumentException e) {
        throw new ValidationException(e.getMessage());
    }
    return dataSource;
}
Also used : ValidationException(org.apache.calcite.tools.ValidationException) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier)

Example 12 with ValidationException

use of org.apache.calcite.tools.ValidationException in project druid by apache.

the class DruidPlanner method validate.

/**
 * Validates a SQL query and populates {@link PlannerContext#getResourceActions()}.
 *
 * @return set of {@link Resource} corresponding to any Druid datasources or views which are taking part in the query.
 */
public ValidationResult validate() throws SqlParseException, ValidationException {
    resetPlanner();
    final ParsedNodes parsed = ParsedNodes.create(planner.parse(plannerContext.getSql()));
    final SqlValidator validator = getValidator();
    final SqlNode validatedQueryNode;
    try {
        validatedQueryNode = validator.validate(rewriteDynamicParameters(parsed.getQueryNode()));
    } catch (RuntimeException e) {
        throw new ValidationException(e);
    }
    SqlResourceCollectorShuttle resourceCollectorShuttle = new SqlResourceCollectorShuttle(validator, plannerContext);
    validatedQueryNode.accept(resourceCollectorShuttle);
    final Set<ResourceAction> resourceActions = new HashSet<>(resourceCollectorShuttle.getResourceActions());
    if (parsed.getInsertNode() != null) {
        final String targetDataSource = validateAndGetDataSourceForInsert(parsed.getInsertNode());
        resourceActions.add(new ResourceAction(new Resource(targetDataSource, ResourceType.DATASOURCE), Action.WRITE));
    }
    plannerContext.setResourceActions(resourceActions);
    return new ValidationResult(resourceActions);
}
Also used : ValidationException(org.apache.calcite.tools.ValidationException) SqlValidator(org.apache.calcite.sql.validate.SqlValidator) Resource(org.apache.druid.server.security.Resource) SqlNode(org.apache.calcite.sql.SqlNode) ResourceAction(org.apache.druid.server.security.ResourceAction) HashSet(java.util.HashSet)

Example 13 with ValidationException

use of org.apache.calcite.tools.ValidationException in project druid by druid-io.

the class DruidPlanner method plan.

public PlannerResult plan(final String sql) throws SqlParseException, ValidationException, RelConversionException {
    SqlExplain explain = null;
    SqlNode parsed = planner.parse(sql);
    if (parsed.getKind() == SqlKind.EXPLAIN) {
        explain = (SqlExplain) parsed;
        parsed = explain.getExplicandum();
    }
    final SqlNode validated = planner.validate(parsed);
    final RelRoot root = planner.rel(validated);
    try {
        return planWithDruidConvention(explain, root);
    } catch (RelOptPlanner.CannotPlanException e) {
        // Try again with BINDABLE convention. Used for querying Values, metadata tables, and fallback.
        try {
            return planWithBindableConvention(explain, root);
        } catch (Exception e2) {
            e.addSuppressed(e2);
            throw e;
        }
    }
}
Also used : SqlExplain(org.apache.calcite.sql.SqlExplain) RelRoot(org.apache.calcite.rel.RelRoot) RelOptPlanner(org.apache.calcite.plan.RelOptPlanner) ValidationException(org.apache.calcite.tools.ValidationException) RelConversionException(org.apache.calcite.tools.RelConversionException) SqlParseException(org.apache.calcite.sql.parser.SqlParseException) SqlNode(org.apache.calcite.sql.SqlNode)

Example 14 with ValidationException

use of org.apache.calcite.tools.ValidationException in project druid by apache.

the class DruidPlanner method plan.

/**
 * Plan an SQL query for execution, returning a {@link PlannerResult} which can be used to actually execute the query.
 *
 * Ideally, the query can be planned into a native Druid query, using {@link #planWithDruidConvention}, but will
 * fall-back to {@link #planWithBindableConvention} if this is not possible.
 *
 * In some future this could perhaps re-use some of the work done by {@link #validate()}
 * instead of repeating it, but that day is not today.
 */
public PlannerResult plan() throws SqlParseException, ValidationException, RelConversionException {
    resetPlanner();
    final ParsedNodes parsed = ParsedNodes.create(planner.parse(plannerContext.getSql()));
    try {
        if (parsed.getIngestionGranularity() != null) {
            plannerContext.getQueryContext().put(DruidSqlInsert.SQL_INSERT_SEGMENT_GRANULARITY, plannerContext.getJsonMapper().writeValueAsString(parsed.getIngestionGranularity()));
        }
    } catch (JsonProcessingException e) {
        throw new ValidationException("Unable to serialize partition granularity.");
    }
    // the planner's type factory is not available until after parsing
    this.rexBuilder = new RexBuilder(planner.getTypeFactory());
    final SqlNode parameterizedQueryNode = rewriteDynamicParameters(parsed.getQueryNode());
    final SqlNode validatedQueryNode = planner.validate(parameterizedQueryNode);
    final RelRoot rootQueryRel = planner.rel(validatedQueryNode);
    try {
        return planWithDruidConvention(rootQueryRel, parsed.getExplainNode(), parsed.getInsertNode());
    } catch (Exception e) {
        Throwable cannotPlanException = Throwables.getCauseOfType(e, RelOptPlanner.CannotPlanException.class);
        if (null == cannotPlanException) {
            // Not a CannotPlanningException, rethrow without trying with bindable
            throw e;
        }
        // any error, if it is plannable by the bindable convention
        if (parsed.getInsertNode() == null) {
            // Try again with BINDABLE convention. Used for querying Values and metadata tables.
            try {
                return planWithBindableConvention(rootQueryRel, parsed.getExplainNode());
            } catch (Exception e2) {
                e.addSuppressed(e2);
            }
        }
        Logger logger = log;
        if (!QueryContexts.isDebug(plannerContext.getQueryContext())) {
            logger = log.noStackTrace();
        }
        String errorMessage = buildSQLPlanningErrorMessage(cannotPlanException);
        logger.warn(e, errorMessage);
        throw new UnsupportedSQLQueryException(errorMessage);
    }
}
Also used : ValidationException(org.apache.calcite.tools.ValidationException) RexBuilder(org.apache.calcite.rex.RexBuilder) RelRoot(org.apache.calcite.rel.RelRoot) Logger(org.apache.druid.java.util.common.logger.Logger) EmittingLogger(org.apache.druid.java.util.emitter.EmittingLogger) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ValidationException(org.apache.calcite.tools.ValidationException) SqlParseException(org.apache.calcite.sql.parser.SqlParseException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) RelConversionException(org.apache.calcite.tools.RelConversionException) SqlNode(org.apache.calcite.sql.SqlNode)

Example 15 with ValidationException

use of org.apache.calcite.tools.ValidationException in project druid by apache.

the class SqlLifecycle method plan.

/**
 * Plan the query to enable execution.
 *
 * If successful, the lifecycle will first transition from {@link State#AUTHORIZED} to {@link State#PLANNED}.
 */
public void plan() throws RelConversionException {
    transition(State.AUTHORIZED, State.PLANNED);
    Preconditions.checkNotNull(plannerContext, "Cannot plan, plannerContext is null");
    try (DruidPlanner planner = plannerFactory.createPlannerWithContext(plannerContext)) {
        this.plannerResult = planner.plan();
    }// we can't collapse catch clauses since SqlPlanningException has type-sensitive constructors.
     catch (SqlParseException e) {
        throw new SqlPlanningException(e);
    } catch (ValidationException e) {
        throw new SqlPlanningException(e);
    }
}
Also used : ValidationException(org.apache.calcite.tools.ValidationException) SqlParseException(org.apache.calcite.sql.parser.SqlParseException) DruidPlanner(org.apache.druid.sql.calcite.planner.DruidPlanner)

Aggregations

ValidationException (org.apache.calcite.tools.ValidationException)29 SqlParseException (org.apache.calcite.sql.parser.SqlParseException)15 SqlNode (org.apache.calcite.sql.SqlNode)14 RelConversionException (org.apache.calcite.tools.RelConversionException)12 RelRoot (org.apache.calcite.rel.RelRoot)7 Planner (org.apache.calcite.tools.Planner)6 FrameworkConfig (org.apache.calcite.tools.FrameworkConfig)5 PreparedStatement (java.sql.PreparedStatement)4 SQLException (java.sql.SQLException)4 SqlPrettyWriter (org.apache.calcite.sql.pretty.SqlPrettyWriter)4 SQLPlannedOperationStatement (herddb.model.commands.SQLPlannedOperationStatement)3 ScanStatement (herddb.model.commands.ScanStatement)3 HashSet (java.util.HashSet)3 SqlValidator (org.apache.calcite.sql.validate.SqlValidator)3 Resource (org.apache.druid.server.security.Resource)3 ResourceAction (org.apache.druid.server.security.ResourceAction)3 DruidPlanner (org.apache.druid.sql.calcite.planner.DruidPlanner)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 HerdDBInternalException (herddb.core.HerdDBInternalException)2 DataScanner (herddb.model.DataScanner)2