private String createTemporaryTableName() { return rewritePrefix.getSuffix() + UUID.randomUUID().toString().replace("-", ""); }
public boolean canResolve(QualifiedName name) { if (!this.name.isPresent()) { return false; } // TODO: need to know whether the qualified name and the name of this field were quoted return matchesPrefix(name.getPrefix()) && this.name.get().equalsIgnoreCase(name.getSuffix()); }
@Override protected RowExpression visitFunctionCall(FunctionCall node, Void context) { List<RowExpression> arguments = node.getArguments().stream() .map(value -> process(value, context)) .collect(toImmutableList()); List<TypeSignature> argumentTypes = arguments.stream() .map(RowExpression::getType) .map(Type::getTypeSignature) .collect(toImmutableList()); Signature signature = new Signature(node.getName().getSuffix(), functionKind, getType(node).getTypeSignature(), argumentTypes); return call(signature, getType(node), arguments); }
public static CatalogSchemaName createCatalogSchemaName(Session session, Node node, Optional<QualifiedName> schema) { String catalogName = session.getCatalog().orElse(null); String schemaName = session.getSchema().orElse(null); if (schema.isPresent()) { List<String> parts = schema.get().getParts(); if (parts.size() > 2) { throw new SemanticException(INVALID_SCHEMA_NAME, node, "Too many parts in schema name: %s", schema.get()); } if (parts.size() == 2) { catalogName = parts.get(0); } schemaName = schema.get().getSuffix(); } if (catalogName == null) { throw new SemanticException(CATALOG_NOT_SPECIFIED, node, "Catalog must be specified when session catalog is not set"); } if (schemaName == null) { throw new SemanticException(SCHEMA_NOT_SPECIFIED, node, "Schema must be specified when session schema is not set"); } return new CatalogSchemaName(catalogName, schemaName); }
@Override protected String visitFunctionCall(FunctionCall node, Void context) { StringBuilder builder = new StringBuilder(); String arguments = joinExpressions(node.getArguments()); if (node.getArguments().isEmpty() && "count".equalsIgnoreCase(node.getName().getSuffix())) { arguments = "*"; } if (node.isDistinct()) { arguments = "DISTINCT " + arguments; } builder.append(formatQualifiedName(node.getName())) .append('(').append(arguments); if (node.getOrderBy().isPresent()) { builder.append(' ').append(formatOrderBy(node.getOrderBy().get(), parameters)); } builder.append(')'); if (node.getFilter().isPresent()) { builder.append(" FILTER ").append(visitFilter(node.getFilter().get(), context)); } if (node.getWindow().isPresent()) { builder.append(" OVER ").append(visitWindow(node.getWindow().get(), context)); } return builder.toString(); }
public Symbol newSymbol(Expression expression, Type type, String suffix) { String nameHint = "expr"; if (expression instanceof Identifier) { nameHint = ((Identifier) expression).getValue(); } else if (expression instanceof FunctionCall) { nameHint = ((FunctionCall) expression).getName().getSuffix(); } else if (expression instanceof SymbolReference) { nameHint = ((SymbolReference) expression).getName(); } else if (expression instanceof GroupingOperation) { nameHint = "grouping"; } return newSymbol(nameHint, type, suffix); }
@Test public void testCreateTableAsSelectDifferentCatalog() throws Exception { handle.execute("CREATE TABLE \"my_test_table2\" (column1 BIGINT, column2 DOUBLE)"); SqlParser parser = new SqlParser(); Query query = new Query(CATALOG, SCHEMA, ImmutableList.of(), "CREATE TABLE public.my_test_table2 AS SELECT 1 column1, 2E0 column2", ImmutableList.of(), null, null, ImmutableMap.of()); QueryRewriter rewriter = new QueryRewriter(parser, URL, QualifiedName.of("other_catalog", "other_schema", "tmp_"), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), 1, new Duration(10, SECONDS)); Query rewrittenQuery = rewriter.shadowQuery(query); assertEquals(rewrittenQuery.getPreQueries().size(), 1); CreateTableAsSelect createTableAs = (CreateTableAsSelect) parser.createStatement(rewrittenQuery.getPreQueries().get(0)); assertEquals(createTableAs.getName().getParts().size(), 3); assertEquals(createTableAs.getName().getPrefix().get(), QualifiedName.of("other_catalog", "other_schema")); assertTrue(createTableAs.getName().getSuffix().startsWith("tmp_")); assertFalse(createTableAs.getName().getSuffix().contains("my_test_table")); }
@Test public void testCreateTableAsSelect() throws Exception { handle.execute("CREATE TABLE \"my_test_table\" (column1 BIGINT, column2 DOUBLE)"); SqlParser parser = new SqlParser(); Query query = new Query(CATALOG, SCHEMA, ImmutableList.of(), "CREATE TABLE my_test_table AS SELECT 1 column1, CAST('2.0' AS DOUBLE) column2 LIMIT 1", ImmutableList.of(), null, null, ImmutableMap.of()); QueryRewriter rewriter = new QueryRewriter(parser, URL, QualifiedName.of("tmp_"), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), 1, new Duration(10, SECONDS)); Query rewrittenQuery = rewriter.shadowQuery(query); assertEquals(rewrittenQuery.getPreQueries().size(), 1); assertEquals(rewrittenQuery.getPostQueries().size(), 1); CreateTableAsSelect createTableAs = (CreateTableAsSelect) parser.createStatement(rewrittenQuery.getPreQueries().get(0)); assertEquals(createTableAs.getName().getParts().size(), 1); assertTrue(createTableAs.getName().getSuffix().startsWith("tmp_")); assertFalse(createTableAs.getName().getSuffix().contains("my_test_table")); assertEquals(statementToQueryType(parser, rewrittenQuery.getQuery()), READ); Table table = new Table(createTableAs.getName()); SingleColumn column1 = new SingleColumn(new FunctionCall(QualifiedName.of("checksum"), ImmutableList.of(new Identifier("COLUMN1")))); SingleColumn column2 = new SingleColumn(new FunctionCall(QualifiedName.of("checksum"), ImmutableList.of(new FunctionCall(QualifiedName.of("round"), ImmutableList.of(new Identifier("COLUMN2"), new LongLiteral("1")))))); Select select = new Select(false, ImmutableList.of(column1, column2)); QuerySpecification querySpecification = new QuerySpecification(select, Optional.of(table), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); assertEquals(parser.createStatement(rewrittenQuery.getQuery()), new com.facebook.presto.sql.tree.Query(Optional.empty(), querySpecification, Optional.empty(), Optional.empty())); assertEquals(parser.createStatement(rewrittenQuery.getPostQueries().get(0)), new DropTable(createTableAs.getName(), true)); }
String name = table.getName().getSuffix();
assertEquals(createTable.getName().getParts().size(), 3); assertEquals(createTable.getName().getPrefix().get(), QualifiedName.of("other_catalog", "other_schema")); assertTrue(createTable.getName().getSuffix().startsWith("tmp_")); assertFalse(createTable.getName().getSuffix().contains("test_insert_table"));
private Function<QualifiedName, String> tableNameMapper(RequestContext context, Map<MaterializedView, MaterializedViewExecution> materializedViews, Optional<QuerySampling> sample, String defaultSchema, Map<String, String> sessionParameters) { return (node) -> { if (node.getPrefix().isPresent() && node.getPrefix().get().toString().equals("materialized")) { MaterializedView materializedView; try { materializedView = materializedViewService.get(context.project, node.getSuffix()); } catch (NotExistsException e) { throw new MaterializedViewNotExists(node.getSuffix()); } MaterializedViewExecution materializedViewExecution = materializedViews.computeIfAbsent(materializedView, (key) -> materializedViewService.lockAndUpdateView(context, materializedView)); if (materializedViewExecution == null) { throw new IllegalStateException(); } return materializedViewExecution.computeQuery; } if (!node.getPrefix().isPresent() && defaultSchema != null) { node = QualifiedName.of(defaultSchema, node.getSuffix()); } return executor.formatTableReference(context.project, node, sample, sessionParameters); }; }
@Override protected Void visitTable(Table node, Integer indent) { if (!node.getName().getPrefix().isPresent() && queryWithTables.contains(node.getName().getSuffix().toLowerCase(Locale.ENGLISH))) { builder.append(formatName(node.getName().toString(), escapeIdentifier)); return null; } builder.append(tableNameMapper.apply(node.getName())); return null; }
@Override protected String visitFunctionCall(FunctionCall node, Void context) { StringBuilder builder = new StringBuilder(); String arguments = joinExpressions(node.getArguments()); if (node.getArguments().isEmpty() && "count".equalsIgnoreCase(node.getName().getSuffix())) { arguments = "*"; } if (node.isDistinct()) { arguments = "DISTINCT " + arguments; } String name; if (node.getName().getParts().size() > 1) { name = formatQualifiedName(node.getName(), escape); } else { // for Mysql - > SELECT `count`(1) doesn't work name = node.getName().getSuffix(); } builder.append(name).append('(').append(arguments).append(')'); if (node.getFilter().isPresent()) { builder.append(" FILTER ").append(visitFilter(node.getFilter().get(), context)); } if (node.getWindow().isPresent()) { builder.append(" OVER ").append(visitWindow(node.getWindow().get(), context)); } return builder.toString(); }
private QueryExecution getSingleQueryExecution(String query, List<CustomDataSource> type) { char seperator = dbSeparator(type.get(0).type); StringBuilder builder = new StringBuilder(); Statement statement = sqlParser.createStatement(query, new ParsingOptions()); try { new RakamSqlFormatter.Formatter(builder, qualifiedName -> { String schema = qualifiedName.getPrefix().get().toString(); CustomDataSource customDataSource1 = type.stream() .filter(e -> e.schemaName.equals(schema)).findAny() .orElseThrow(() -> new RakamException("Cross database operations are not supported.", BAD_REQUEST)); return SupportedCustomDatabase.getAdapter(customDataSource1.type).getTableMapper() .apply(customDataSource1.options, qualifiedName.getSuffix()); }, seperator) { }.process(statement, 1); } catch (UnsupportedOperationException e) { return null; } String sqlQuery = builder.toString(); return new JDBCQueryExecution(() -> SupportedCustomDatabase.getAdapter(type.get(0).type).getDataSource().openConnection(type.get(0).options), sqlQuery, false, Optional.empty(), false); }
switch (prefix) { case "collection": return checkProject(project, '"') + "." + checkCollection(name.getSuffix()) + sample.map(e -> " TABLESAMPLE " + e.method.name() + "(" + e.percentage + ")").orElse(""); case "continuous": return checkProject(project, '"') + "." + checkCollection(CONTINUOUS_QUERY_PREFIX + name.getSuffix()); case "materialized": return checkProject(project, '"') + "." + checkCollection(MATERIALIZED_VIEW_PREFIX + name.getSuffix()); default: if (customDataSource == null) { return checkProject(prefix, '"') + "." + checkCollection(name.getSuffix()); } else if (name.getSuffix().equals("users")) { if (userServiceIsPostgresql) { return checkProject(project, '"') + "._users"; if (name.getSuffix().equals("_all") && !name.getPrefix().isPresent()) { List<Map.Entry<String, List<SchemaField>>> collections = metastore.getCollections(project).entrySet().stream() .collect(Collectors.toList()); return checkProject(project, '"') + "." + checkCollection(name.getSuffix());
@Override public String formatTableReference(String project, QualifiedName node, Optional<QuerySampling> sample, Map<String, String> sessionParameters) { String prefix = node.getPrefix().map(e -> e.toString()).orElse(null); String suffix = node.getSuffix(); if ("materialized".equals(prefix)) { return getTableReference(project, MATERIALIZED_VIEW_PREFIX + suffix, sample);
referencedCollections.add(name.getSuffix());
public static Symbol fromQualifiedName(QualifiedName name) { Preconditions.checkArgument(!name.getPrefix().isPresent(), "Can't create a symbol from a qualified name with prefix"); return new Symbol(name.getSuffix()); }