@Override public List<SimpleCommandResult> toResult(String sql, SqlNode sqlNode) throws Exception { final SqlLoadMaterialization load = SqlNodeUtil.unwrap(sqlNode, SqlLoadMaterialization.class); if(!SystemUser.SYSTEM_USERNAME.equals(context.getQueryUserName())) { throw SqlExceptionHelper.parseError("$LOAD MATERIALIZATION not supported.", sql, load.getParserPosition()).build(logger); } final ReflectionService service = Preconditions.checkNotNull(context.getAccelerationManager().unwrap(ReflectionService.class), "Couldn't unwrap ReflectionService"); final List<String> components = normalizeComponents(load.getMaterializationPath()); if (components == null) { throw SqlExceptionHelper.parseError("Invalid materialization path.", sql, load.getParserPosition()).build(logger); } final ReflectionId reflectionId = new ReflectionId(components.get(0)); final Optional<ReflectionGoal> goalOptional = service.getGoal(reflectionId); if (!goalOptional.isPresent()) { throw SqlExceptionHelper.parseError("Unknown reflection id.", sql, load.getParserPosition()).build(logger); } final ReflectionGoal goal = goalOptional.get(); final MaterializationId materializationId = new MaterializationId(components.get(1)); final Optional<Materialization> materializationOpt = service.getMaterialization(materializationId); if (!materializationOpt.isPresent()) { throw SqlExceptionHelper.parseError("Unknown materialization id.", sql, load.getParserPosition()).build(logger); } final Materialization materialization = materializationOpt.get(); // if the user already made changes to the reflection goal, let's stop right here Preconditions.checkState(Objects.equals(goal.getTag(), materialization.getReflectionGoalVersion()), "materialization no longer matches its goal"); refreshMetadata(goal, materialization); return Collections.singletonList(SimpleCommandResult.successful("Materialization metadata loaded.")); }
private RelNode getPlan(SqlHandlerConfig sqlHandlerConfig, List<String> refreshTablePath, PlanNormalizer planNormalizer) { SqlSelect select = new SqlSelect( SqlParserPos.ZERO, new SqlNodeList(SqlParserPos.ZERO), new SqlNodeList(ImmutableList.<SqlNode>of(SqlIdentifier.star(SqlParserPos.ZERO)), SqlParserPos.ZERO), new SqlIdentifier(refreshTablePath, SqlParserPos.ZERO), null, null, null, null, null, null, null ); try { ConvertedRelNode converted = PrelTransformer.validateAndConvert(sqlHandlerConfig, select, planNormalizer); return converted.getConvertedNode(); } catch (ForemanSetupException | RelConversionException | ValidationException e) { throw Throwables.propagate(SqlExceptionHelper.coerceException(logger, select.toString(), e, false)); } }
public static Exception coerceException(Logger logger, String sql, Exception e, boolean coerceToPlan){ if(e instanceof UserException){ return e; } else if(e instanceof ValidationException){ throw validationError(sql, (ValidationException) e).build(logger); } else if (e instanceof AccessControlException){ throw UserException.permissionError(e) .addContext(SQL_QUERY_CONTEXT, sql) .build(logger); } else if (e instanceof SqlUnsupportedException){ throw UserException.unsupportedError(e) .addContext(SQL_QUERY_CONTEXT, sql) .build(logger); } else if (e instanceof IOException || e instanceof RelConversionException){ return new QueryInputException("Failure handling SQL.", e); } else if (coerceToPlan){ throw planError(sql, e).build(logger); } return e; } }
throw SqlExceptionHelper.parseError("$COMPACT REFRESH not supported.", sql, compact.getParserPosition()) .build(logger); throw SqlExceptionHelper.parseError("Unknown materialization", sql, compact.getParserPosition()) .build(logger); Optional<ReflectionGoal> goalOpt = service.getGoal(reflectionId); if(!goalOpt.isPresent()) { throw SqlExceptionHelper.parseError("Unknown reflection id.", sql, compact.getParserPosition()).build(logger); throw SqlExceptionHelper.parseError("Unknown reflection id.", sql, compact.getParserPosition()).build(logger); throw SqlExceptionHelper.parseError("Unknown materialization id", sql, compact.getParserPosition()).build(logger); throw SqlExceptionHelper.parseError("Invalid materialization", sql, compact.getParserPosition()).build(logger); throw SqlExceptionHelper.parseError("Unknown new materialization id", sql, compact.getParserPosition()).build(logger); throw SqlExceptionHelper.coerceException(logger, sql, e, true);
throw SqlExceptionHelper.validationError(query.getSql(), e) .build(logger); } catch (AccessControlException e) {
public static UserException.Builder parseError(String message, String query, SqlParserPos pos) { return addParseContext(UserException.parseError().message(message), query, pos); }
throw SqlExceptionHelper.parseError("$MATERIALIZE not supported.", sql, materialize.getParserPosition()).build(logger); Optional<ReflectionGoal> goalOpt = service.getGoal(reflectionId); if(!goalOpt.isPresent()) { throw SqlExceptionHelper.parseError("Unknown reflection id.", sql, materialize.getReflectionIdPos()).build(logger); throw SqlExceptionHelper.parseError("Unknown reflection id.", sql, materialize.getReflectionIdPos()).build(logger); throw SqlExceptionHelper.parseError("Unknown materialization id.", sql, materialize.getReflectionIdPos()).build(logger); throw SqlExceptionHelper.coerceException(logger, sql, ex, true);
public static UserException.Builder parseError(String query, SqlParseException ex) { final SqlParserPos pos = ex.getPos(); if (pos == null) { return UserException .parseError(ex) .addContext(SQL_QUERY_CONTEXT, query); } else { // Calcite convention is to return column and line numbers as 1-based inclusive positions. return addParseContext(UserException.parseError(ex), query, pos); } }
public SqlNode parse(String sql) { try { SqlParser parser = SqlParser.create(sql, parserConfig); return parser.parseStmt().accept(STRING_LITERAL_CONVERTER); } catch (SqlParseException e) { UserException.Builder builder = SqlExceptionHelper.parseError(sql, e); builder.message(isInnerQuery ? SqlExceptionHelper.INNER_QUERY_PARSING_ERROR : SqlExceptionHelper.QUERY_PARSING_ERROR); throw builder.build(logger); } }
@Override public double plan() throws Exception { try{ final RecordingObserver recording = new RecordingObserver(); final AttemptObservers observers = AttemptObservers.of(observer, recording); observers.planStart(sql); plan = handler.getPlan(config.cloneWithNewObserver(observers), sql, sqlNode); PreparedPlan prepared = new PreparedPlan(context.getQueryId(), context.getQueryUserName(), sql, plan, recording); final Long handle = PREPARE_ID.getAndIncrement(); state = ServerPreparedStatementState.newBuilder() .setHandle(handle) .setSqlQuery(sql) .setPrepareId(context.getQueryId()) .build(); planCache.put(handle, prepared); // record a partial plan so that we can grab metadata and use it (for example during view creation of via sql). observers.planCompleted(new ExecutionPlan(plan, ImmutableList.of(), ImmutableList.of())); return 1; }catch(Exception ex){ throw SqlExceptionHelper.coerceException(logger, sql, ex, true); } }
@Test public void convertExceptionToQueryErrors() { // Fake logger to not pollute logs org.slf4j.Logger logger = mock(org.slf4j.Logger.class); SqlParseException parseException = new SqlParseException("test message", new SqlParserPos(7, 42, 13, 57), null, null, null); UserException userException = SqlExceptionHelper.parseError("SELECT FOO", parseException) .build(logger); List<QueryError> errors = QueryError.of(userException); assertEquals(1, errors.size()); QueryError error = errors.get(0); assertEquals("test message", error.getMessage()); assertEquals(7, error.getRange().getStartLine()); assertEquals(42, error.getRange().getStartColumn()); assertEquals(13, error.getRange().getEndLine()); assertEquals(57, error.getRange().getEndColumn()); }
@Override public PhysicalPlan getPlan(SqlHandlerConfig config, String sql, SqlNode sqlNode) throws Exception { try{ final ConvertedRelNode convertedRelNode = PrelTransformer.validateAndConvert(config, sqlNode); final RelDataType validatedRowType = convertedRelNode.getValidatedRowType(); final RelNode queryRelNode = convertedRelNode.getConvertedNode(); final Rel drel = PrelTransformer.convertToDrel(config, queryRelNode, validatedRowType); final Pair<Prel, String> convertToPrel = PrelTransformer.convertToPrel(config, drel); final Prel prel = convertToPrel.getKey(); textPlan = convertToPrel.getValue(); final PhysicalOperator pop = PrelTransformer.convertToPop(config, prel); final PhysicalPlan plan = PrelTransformer.convertToPlan(config, pop); logger.debug("Final Physical Plan {}", textPlan); PrelTransformer.log(config, "Dremio Plan", plan, logger); return plan; }catch(Exception ex){ throw SqlExceptionHelper.coerceException(logger, sql, ex, true); } }
@Test public void convertExceptionToQueryErrorsWithPosition() { // Fake logger to not pollute logs org.slf4j.Logger logger = mock(org.slf4j.Logger.class); SqlParseException parseException = new SqlParseException("test message 2", new SqlParserPos(7, 42, 7, 42), null, null, null); UserException userException = SqlExceptionHelper.parseError("SELECT BAR", parseException) .build(logger); List<QueryError> errors = QueryError.of(userException); assertEquals(1, errors.size()); QueryError error = errors.get(0); assertEquals("test message 2", error.getMessage()); assertEquals(7, error.getRange().getStartLine()); assertEquals(42, error.getRange().getStartColumn()); assertEquals(7, error.getRange().getEndLine()); assertEquals(42, error.getRange().getEndColumn()); } }
throw Throwables.propagate(SqlExceptionHelper.coerceException(logger, select.toString(), e, false));
@Test public void convertExceptionToFailureInfo() { // Fake logger to not pollute logs org.slf4j.Logger logger = mock(org.slf4j.Logger.class); SqlParseException parseException = new SqlParseException("test message", new SqlParserPos(7, 42, 13, 57), null, null, null); UserException userException = SqlExceptionHelper.parseError("SELECT FOO", parseException) .build(logger); String verboseError = userException.getVerboseMessage(false); JobFailureInfo jobFailureInfo = JobsServiceUtil.toFailureInfo(verboseError); assertEquals(JobFailureInfo.Type.PARSE, jobFailureInfo.getType()); assertEquals(1, jobFailureInfo.getErrorsList().size()); JobFailureInfo.Error error = jobFailureInfo.getErrorsList().get(0); assertEquals("test message", error.getMessage()); assertEquals(7, (int) error.getStartLine()); assertEquals(42, (int) error.getStartColumn()); assertEquals(13, (int) error.getEndLine()); assertEquals(57, (int) error.getEndColumn()); } }
throw SqlExceptionHelper.coerceException(logger, sql, ex, true);
throw SqlExceptionHelper.coerceException(logger, sql, ex, true);