@Override public CompletableFuture<?> execute(CreateView statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine) { Session session = stateMachine.getSession(); QualifiedObjectName name = createQualifiedObjectName(session, statement, statement.getName()); accessControl.checkCanCreateView(session.getRequiredTransactionId(), session.getIdentity(), name); String sql = getFormattedSql(statement); Analysis analysis = analyzeStatement(statement, session, metadata); List<ViewColumn> columns = analysis.getOutputDescriptor() .getVisibleFields().stream() .map(field -> new ViewColumn(field.getName().get(), field.getType())) .collect(toImmutableList()); String data = codec.toJson(new ViewDefinition(sql, session.getCatalog(), session.getSchema(), columns, Optional.of(session.getUser()))); metadata.createView(session, name, data, statement.isReplace()); return completedFuture(null); }
private String getFormattedSql(CreateView statement) { Query query = statement.getQuery(); String sql = formatSql(query); // verify round-trip Statement parsed; try { parsed = sqlParser.createStatement(sql); } catch (ParsingException e) { throw new PrestoException(INTERNAL_ERROR, "Formatted query does not parse: " + query); } if (!query.equals(parsed)) { throw new PrestoException(INTERNAL_ERROR, "Query does not round-trip: " + query); } return sql; }
@Override protected RelationType visitCreateView(CreateView node, AnalysisContext context) { analysis.setUpdateType("CREATE VIEW"); // analyze the query that creates the view StatementAnalyzer analyzer = new StatementAnalyzer( analysis, metadata, sqlParser, new ViewAccessControl(accessControl), session, experimentalSyntaxEnabled, queryExplainer); RelationType descriptor = analyzer.process(node.getQuery(), new AnalysisContext()); QualifiedObjectName viewName = createQualifiedObjectName(session, node, node.getName()); accessControl.checkCanCreateView(session.getRequiredTransactionId(), session.getIdentity(), viewName); validateColumnNames(node, descriptor); return descriptor; }
@Override protected Void visitCreateView(CreateView node, Integer indent) { builder.append("CREATE "); if (node.isReplace()) { builder.append("OR REPLACE "); } builder.append("VIEW ") .append(node.getName()) .append(" AS\n"); process(node.getQuery(), indent); return null; }
@Override public int executeUpdate(String sql) throws SQLException { //System.out.println("QUERY: ["+sql+"]"); sql = sql.replaceAll("\r", " ").replaceAll("\n", " ").trim(); // custom stuff to support UPDATE statements since Presto does not parse it if(sql.toLowerCase().startsWith("update")){ return updateState.execute(sql); } com.facebook.presto.sql.tree.Statement statement = parser.createStatement(sql); if(statement instanceof Query) throw new SQLException("A regular query cannot be executed as an Update"); if(statement instanceof Insert){ //if(connection.getSchema() == null) throw new SQLException("No active index set for this driver. Pleas specify an active index or alias by executing 'USE <index/alias>' first"); return updateState.execute(sql, (Insert)statement, connection.getSchema()); }else if(statement instanceof Delete){ if(connection.getSchema() == null) throw new SQLException("No active index set for this driver. Pleas specify an active index or alias by executing 'USE <index/alias>' first"); return updateState.execute(sql, (Delete)statement, connection.getSchema()); }else if(statement instanceof CreateTable){ return updateState.execute(sql, (CreateTable)statement, connection.getSchema()); }else if(statement instanceof CreateTableAsSelect){ return updateState.execute(sql, (CreateTableAsSelect)statement, connection.getSchema()); }else if(statement instanceof CreateView){ return updateState.execute(sql, (CreateView)statement, connection.getSchema()); }else if(statement instanceof Use){ connection.setSchema( ((Use)statement).getSchema()); //connection.getTypeMap(); // updates the type mappings found in properties return 0; }else if(statement instanceof DropTable){ return updateState.execute(sql, (DropTable)statement); }else if(statement instanceof DropView){ return updateState.execute(sql, (DropView)statement); }throw new SQLFeatureNotSupportedException("Unable to parse provided update sql"); }
/** * Executes the {@link BulkRequest} being hold by this state. * @return an integer indicator for each executed request: Statement.SUCCESS_NO_INFO for success, * else Statement.EXECUTE_FAILED) */ public int[] executeBulk(){ int[] result = new int[bulkList.size()]; SqlParser parser = new SqlParser(); for(int i=0; i<bulkList.size(); i++) try{ String sql = bulkList.get(i); com.facebook.presto.sql.tree.Statement st = parser.createStatement(sql); if(st instanceof DropTable){ this.execute(sql, (DropTable)st); }else if(st instanceof DropView){ this.execute(sql, (DropView)st); }else if(st instanceof CreateTable){ this.execute(sql, (CreateTable)st, this.statement.getConnection().getSchema()); }else if(st instanceof CreateTableAsSelect){ this.execute(sql, (CreateTableAsSelect)st, this.statement.getConnection().getSchema()); }else if(st instanceof CreateView){ this.execute(sql, (CreateView)st, this.statement.getConnection().getSchema()); }else if(st instanceof Delete){ this.execute(sql, (Delete)st, this.statement.getConnection().getSchema()); }else if(st instanceof Insert){ this.execute(sql, (Insert)st, this.statement.getConnection().getSchema()); } result[i]= Statement.SUCCESS_NO_INFO; }catch (Exception e){ result[i] = Statement.EXECUTE_FAILED; } this.clearBulk(); return result; }
/** * Creates a view (elasticsearch alias) with given name and query * @param sql * @param create * @param index * @return * @throws SQLException */ public int execute(String sql, CreateView create, String index) throws SQLException{ String alias = create.getName().toString(); alias = Heading.findOriginal(sql, alias, "\\s+view\\s+", "\\s+as\\s+"); QueryBody queryBody = create.getQuery().getQueryBody(); if(!(queryBody instanceof QuerySpecification)) throw new SQLException("Statement does not contain expected query specifiction"); QuerySpecification querySpec = (QuerySpecification)queryBody; if(!querySpec.getFrom().isPresent()) throw new SQLException("Add atleast one INDEX to the query to create the view from"); QueryState state = new BasicQueryState(sql, new Heading(), props); List<QuerySource> relations = new RelationParser().process(querySpec.getFrom().get(), null); String[] indices = new String[relations.size()]; for(int i=0; i<relations.size(); i++) indices[i] = relations.get(i).getSource(); new SelectParser().process(querySpec.getSelect(), state); IndicesAliasesResponse response; if(querySpec.getWhere().isPresent()){ QueryBuilder query = new WhereParser().process(querySpec.getWhere().get(), state).getQuery(); response = client.admin().indices().prepareAliases().addAlias(indices, alias, query).execute().actionGet(); }else{ response = client.admin().indices().prepareAliases().addAlias(indices, alias).execute().actionGet(); } if(!response.isAcknowledged()) throw new SQLException("Elasticsearch failed to create the specified alias"); this.statement.getConnection().getTypeMap(); // trigger a reload of the table&column set for the connection return 0; // the number of altered rows }
@Override public Node visitCreateView(SqlBaseParser.CreateViewContext context) { return new CreateView( getLocation(context), getQualifiedName(context.qualifiedName()), (Query) visit(context.query()), context.REPLACE() != null); }
@Test public void testCreateView() throws Exception { assertStatement("CREATE VIEW a AS SELECT * FROM t", new CreateView( QualifiedName.of("a"), simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false)); assertStatement("CREATE OR REPLACE VIEW a AS SELECT * FROM t", new CreateView( QualifiedName.of("a"), simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), true)); }
@Override protected CatalogSchemaContext visitCreateView(CreateView node, CatalogSchemaContext context) { references.add(qualifiedNameToTable(node.getName(), context)); visitQuery(node.getQuery(), context); return context; }
@Override public String explain(CreateView statement) { return "CREATE VIEW " + statement.getName(); }