public static String formatQualifiedName(QualifiedName name) { return name.getParts().stream() .map(ExpressionFormatter::formatIdentifier) .collect(joining(".")); }
@Override protected Void visitTable(Table node, Integer indentLevel) { String name = Joiner.on('.').join(node.getName().getParts()); print(indentLevel, "Table[" + name + "]"); return null; }
@Override protected Void visitFunctionCall(FunctionCall node, Integer indentLevel) { String name = Joiner.on('.').join(node.getName().getParts()); print(indentLevel, "FunctionCall[" + name + "]"); super.visitFunctionCall(node, indentLevel + 1); return null; }
private static List<String> tryParseParts(Expression base, String fieldName) { if (base instanceof Identifier) { return ImmutableList.of(((Identifier) base).getValue(), fieldName); } else if (base instanceof DereferenceExpression) { QualifiedName baseQualifiedName = getQualifiedName((DereferenceExpression) base); if (baseQualifiedName != null) { List<String> newList = new ArrayList<>(baseQualifiedName.getParts()); newList.add(fieldName); return newList; } } return null; }
public static QualifiedObjectName createQualifiedObjectName(Session session, Node node, QualifiedName name) { requireNonNull(session, "session is null"); requireNonNull(name, "name is null"); if (name.getParts().size() > 3) { throw new PrestoException(SYNTAX_ERROR, format("Too many dots in table name: %s", name)); } List<String> parts = Lists.reverse(name.getParts()); String objectName = parts.get(0); String schemaName = (parts.size() > 1) ? parts.get(1) : session.getSchema().orElseThrow(() -> new SemanticException(SCHEMA_NOT_SPECIFIED, node, "Schema must be specified when session schema is not set")); String catalogName = (parts.size() > 2) ? parts.get(2) : session.getCatalog().orElseThrow(() -> new SemanticException(CATALOG_NOT_SPECIFIED, node, "Catalog must be specified when session catalog is not set")); return new QualifiedObjectName(catalogName, schemaName, objectName); }
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); }
public static Expression from(QualifiedName name) { Expression result = null; for (String part : name.getParts()) { if (result == null) { result = new Identifier(part); } else { result = new DereferenceExpression(result, new Identifier(part)); } } return result; }
@Override public ListenableFuture<?> execute(ResetSession statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters) { List<String> parts = statement.getName().getParts(); if (parts.size() > 2) { throw new SemanticException(INVALID_SESSION_PROPERTY, statement, "Invalid session property '%s'", statement.getName()); } // validate the property name if (parts.size() == 1) { metadata.getSessionPropertyManager().getSystemSessionPropertyMetadata(parts.get(0)) .orElseThrow(() -> new SemanticException(INVALID_SESSION_PROPERTY, statement, "Session property %s does not exist", statement.getName())); } else { ConnectorId connectorId = metadata.getCatalogHandle(stateMachine.getSession(), parts.get(0)) .orElseThrow(() -> new SemanticException(MISSING_CATALOG, statement, "Catalog %s does not exist", parts.get(0))); metadata.getSessionPropertyManager().getConnectorSessionPropertyMetadata(connectorId, parts.get(1)) .orElseThrow(() -> new SemanticException(INVALID_SESSION_PROPERTY, statement, "Session property %s does not exist", statement.getName())); } stateMachine.addResetSessionProperties(statement.getName().toString()); return immediateFuture(null); } }
@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")); }
List<String> parts = propertyName.getParts(); if (parts.size() > 2) { throw new SemanticException(INVALID_SESSION_PROPERTY, statement, "Invalid session property '%s'", propertyName);
@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)); }
assertEquals(createTable.getName().getParts().size(), 3); assertEquals(createTable.getName().getPrefix().get(), QualifiedName.of("other_catalog", "other_schema")); assertTrue(createTable.getName().getSuffix().startsWith("tmp_"));
private static String formatQualifiedName(QualifiedName name, char escape) { List<String> parts = new ArrayList<>(); for (String part : name.getParts()) { parts.add(formatIdentifier(part, escape)); } return Joiner.on('.').join(parts); }
private String getFilterExp(FunnelStep step) { return step.getExpression().map(value -> RakamSqlFormatter.formatExpression(value, name -> name.getParts().stream().map(e -> formatIdentifier(e, '"')).collect(Collectors.joining(".")), ValidationUtil::checkTableColumn, '"')).orElse("true"); }
public String convertFunnel(String project, String connectorField, int idx, FunnelStep funnelStep, Optional<String> dimension, Optional<String> segment, LocalDate startDate, LocalDate endDate) { String table = checkProject(project, '"') + "." + ValidationUtil.checkCollection(funnelStep.getCollection()); Optional<String> filterExp = funnelStep.getExpression().map(value -> RakamSqlFormatter.formatExpression(value, name -> name.getParts().stream().map(e -> formatIdentifier(e, '"')).collect(Collectors.joining(".")), name -> formatIdentifier("step" + idx, '"') + "." + name, '"')); String format = format("SELECT %s %s %s, %d as step, %s from %s %s %s", segment.isPresent() ? "" : dimension.map(ValidationUtil::checkTableColumn).map(v -> v + ",").orElse(""), segment.isPresent() ? format(timeStampMapping.get(FunnelTimestampSegments.valueOf(segment.get().replace(" ", "_").toUpperCase())), dimension.get()) + " as " + checkTableColumn(dimension.get() + "_segment") + "," : "", format(connectorField, "step" + idx), idx + 1, checkTableColumn(projectConfig.getTimeColumn()), table, "step" + idx, filterExp.map(v -> "where " + v).orElse("")); return format; } }
public String convertFunnel(String project, String connectorField, int idx, FunnelStep funnelStep, Optional<String> dimension, Optional<String> segment, LocalDate startDate, LocalDate endDate) { Optional<String> filterExp = funnelStep.getExpression().map(value -> RakamSqlFormatter.formatExpression(value, name -> name.getParts().stream().map(e -> formatIdentifier(e, '"')).collect(Collectors.joining(".")), name -> formatIdentifier("step" + idx, '"') + "." + name, '"')); String format = format("SELECT %s %s, %d as step, %s.%s from %s.%s.%s %s %s %s", dimension.map(ValidationUtil::checkTableColumn).map(v -> "step" + idx + "." + v).map(v -> segment.isPresent() ? applySegment(v, segment) + " as \"" + dimension.orElse("") + "_segment\"" + "," : v + ",").orElse(""), userMappingEnabled ? format("coalesce(mapping._user, %s._user, %s) as _user", "step" + idx, format(connectorField, "step" + idx)) : format(connectorField, "step" + idx), idx + 1, "step" + idx, checkTableColumn(projectConfig.getTimeColumn()), prestoConfig.getColdStorageConnector(), checkProject(project, '"'), checkCollection(funnelStep.getCollection()), "step" + idx, userMappingEnabled ? format("left join %s.%s mapping on (%s.%s is null and mapping.created_at >= date '%s' and mapping.merged_at <= date '%s' and mapping.id = %s.%s)", project, checkCollection(ANONYMOUS_ID_MAPPING), "step" + idx, checkTableColumn(projectConfig.getUserColumn()), startDate.format(ISO_LOCAL_DATE), endDate.format(ISO_LOCAL_DATE), "step" + idx, checkTableColumn(projectConfig.getUserColumn())) : "", filterExp.map(v -> "where " + v).orElse("")); return format; }
if (filter.filterExpression != null) { filterList.add(formatExpression(filter.getExpression(), reference -> reference.getParts().stream() .map(ValidationUtil::checkLiteral).collect(Collectors.joining(".")), '"'));
@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(); }
@Test public void testExpressionFormatterFormatTable() throws Exception { Expression expression = new SqlParser().createExpression("test in (select id from testcollection)"); assertEquals(formatExpression(expression, name -> "\"schema\"." + name.getParts().stream().map(e -> formatIdentifier(e, '"')).collect(Collectors.joining(".")), name -> '"' + name + '"', '"'), "(\"test\" IN (SELECT \"id\"\n" + "FROM\n" + " \"schema\".\"testcollection\"\n" + "))"); } }