private InternalTable buildColumns(
     Session session, String catalogName, Map<String, NullableValue> filters) {
   InternalTable.Builder table =
       InternalTable.builder(informationSchemaTableColumns(TABLE_COLUMNS));
   for (Entry<QualifiedObjectName, List<ColumnMetadata>> entry :
       getColumnsList(session, catalogName, filters).entrySet()) {
     QualifiedObjectName tableName = entry.getKey();
     int ordinalPosition = 1;
     for (ColumnMetadata column : entry.getValue()) {
       if (column.isHidden()) {
         continue;
       }
       table.add(
           tableName.getCatalogName(),
           tableName.getSchemaName(),
           tableName.getObjectName(),
           column.getName(),
           ordinalPosition,
           null,
           "YES",
           column.getType().getDisplayName(),
           column.getComment());
       ordinalPosition++;
     }
   }
   return table.build();
 }
 @Override
 public void checkCanRenameColumn(
     TransactionId transactionId, Identity identity, QualifiedObjectName tableName) {
   if (shouldDenyPrivilege(identity.getUser(), tableName.getObjectName(), RENAME_COLUMN)) {
     denyRenameColumn(tableName.toString());
   }
   super.checkCanRenameColumn(transactionId, identity, tableName);
 }
 @Override
 public void checkCanSelectFromView(
     TransactionId transactionId, Identity identity, QualifiedObjectName viewName) {
   if (shouldDenyPrivilege(identity.getUser(), viewName.getObjectName(), SELECT_VIEW)) {
     denySelectView(viewName.toString());
   }
   if (denyPrivileges.isEmpty()) {
     super.checkCanSelectFromView(transactionId, identity, viewName);
   }
 }
 @Override
 public void checkCanDeleteFromTable(
     TransactionId transactionId, Identity identity, QualifiedObjectName tableName) {
   if (shouldDenyPrivilege(identity.getUser(), tableName.getObjectName(), DELETE_TABLE)) {
     denyDeleteTable(tableName.toString());
   }
   if (denyPrivileges.isEmpty()) {
     super.checkCanDeleteFromTable(transactionId, identity, tableName);
   }
 }
 @Override
 public void checkCanInsertIntoTable(
     TransactionId transactionId, Identity identity, QualifiedObjectName tableName) {
   if (shouldDenyPrivilege(identity.getUser(), tableName.getObjectName(), INSERT_TABLE)) {
     denyInsertTable(tableName.toString());
   }
   if (denyPrivileges.isEmpty()) {
     super.checkCanInsertIntoTable(transactionId, identity, tableName);
   }
 }
 @Override
 public void checkCanCreateViewWithSelectFromTable(
     TransactionId transactionId, Identity identity, QualifiedObjectName tableName) {
   if (shouldDenyPrivilege(
       identity.getUser(), tableName.getObjectName(), CREATE_VIEW_WITH_SELECT_TABLE)) {
     denySelectTable(tableName.toString());
   }
   if (denyPrivileges.isEmpty()) {
     super.checkCanCreateViewWithSelectFromTable(transactionId, identity, tableName);
   }
 }
 @Override
 public void checkCanRenameTable(
     TransactionId transactionId,
     Identity identity,
     QualifiedObjectName tableName,
     QualifiedObjectName newTableName) {
   if (shouldDenyPrivilege(identity.getUser(), tableName.getObjectName(), RENAME_TABLE)) {
     denyRenameTable(tableName.toString(), newTableName.toString());
   }
   if (denyPrivileges.isEmpty()) {
     super.checkCanRenameTable(transactionId, identity, tableName, newTableName);
   }
 }
  private InternalTable buildTables(
      Session session, String catalogName, Map<String, NullableValue> filters) {
    Set<QualifiedObjectName> tables =
        ImmutableSet.copyOf(getTablesList(session, catalogName, filters));
    Set<QualifiedObjectName> views =
        ImmutableSet.copyOf(getViewsList(session, catalogName, filters));

    InternalTable.Builder table =
        InternalTable.builder(informationSchemaTableColumns(TABLE_TABLES));
    for (QualifiedObjectName name : union(tables, views)) {
      // if table and view names overlap, the view wins
      String type = views.contains(name) ? "VIEW" : "BASE TABLE";
      table.add(name.getCatalogName(), name.getSchemaName(), name.getObjectName(), type);
    }
    return table.build();
  }
Exemplo n.º 9
0
  @Override
  public CompletableFuture<?> execute(
      Call call,
      TransactionManager transactionManager,
      Metadata metadata,
      AccessControl accessControl,
      QueryStateMachine stateMachine) {
    if (!stateMachine.isAutoCommit()) {
      throw new PrestoException(
          NOT_SUPPORTED, "Procedures cannot be called within a transaction (use autocommit mode)");
    }

    Session session = stateMachine.getSession();
    QualifiedObjectName procedureName = createQualifiedObjectName(session, call, call.getName());
    Procedure procedure = metadata.getProcedureRegistry().resolve(procedureName);

    // map declared argument names to positions
    Map<String, Integer> positions = new HashMap<>();
    for (int i = 0; i < procedure.getArguments().size(); i++) {
      positions.put(procedure.getArguments().get(i).getName(), i);
    }

    // per specification, do not allow mixing argument types
    Predicate<CallArgument> hasName = argument -> argument.getName().isPresent();
    boolean anyNamed = call.getArguments().stream().anyMatch(hasName);
    boolean allNamed = call.getArguments().stream().allMatch(hasName);
    if (anyNamed && !allNamed) {
      throw new SemanticException(
          INVALID_PROCEDURE_ARGUMENTS, call, "Named and positional arguments cannot be mixed");
    }

    // get the argument names in call order
    Map<String, CallArgument> names = new LinkedHashMap<>();
    for (int i = 0; i < call.getArguments().size(); i++) {
      CallArgument argument = call.getArguments().get(i);
      if (argument.getName().isPresent()) {
        String name = argument.getName().get();
        if (names.put(name, argument) != null) {
          throw new SemanticException(
              INVALID_PROCEDURE_ARGUMENTS, argument, "Duplicate procedure argument: %s", name);
        }
        if (!positions.containsKey(name)) {
          throw new SemanticException(
              INVALID_PROCEDURE_ARGUMENTS, argument, "Unknown argument name: %s", name);
        }
      } else if (i < procedure.getArguments().size()) {
        names.put(procedure.getArguments().get(i).getName(), argument);
      } else {
        throw new SemanticException(
            INVALID_PROCEDURE_ARGUMENTS, call, "Too many arguments for procedure");
      }
    }

    // verify argument count
    if (names.size() < positions.size()) {
      throw new SemanticException(
          INVALID_PROCEDURE_ARGUMENTS, call, "Too few arguments for procedure");
    }

    // get argument values
    Object[] values = new Object[procedure.getArguments().size()];
    for (Entry<String, CallArgument> entry : names.entrySet()) {
      CallArgument callArgument = entry.getValue();
      int index = positions.get(entry.getKey());
      Argument argument = procedure.getArguments().get(index);

      Expression expression = callArgument.getValue();
      Type type = argument.getType();

      Object value = evaluateConstantExpression(expression, type, metadata, session);

      values[index] = toTypeObjectValue(session, type, value);
    }

    // validate arguments
    MethodType methodType = procedure.getMethodHandle().type();
    for (int i = 0; i < procedure.getArguments().size(); i++) {
      if ((values[i] == null) && methodType.parameterType(i).isPrimitive()) {
        String name = procedure.getArguments().get(i).getName();
        throw new PrestoException(
            INVALID_PROCEDURE_ARGUMENT, "Procedure argument cannot be null: " + name);
      }
    }

    // insert session argument
    List<Object> arguments = new ArrayList<>();
    Iterator<Object> valuesIterator = asList(values).iterator();
    for (Class<?> type : methodType.parameterList()) {
      if (ConnectorSession.class.isAssignableFrom(type)) {
        arguments.add(session.toConnectorSession(procedureName.getCatalogName()));
      } else {
        arguments.add(valuesIterator.next());
      }
    }

    try {
      procedure.getMethodHandle().invokeWithArguments(arguments);
    } catch (Throwable t) {
      if (t instanceof InterruptedException) {
        Thread.currentThread().interrupt();
      }
      propagateIfInstanceOf(t, PrestoException.class);
      throw new PrestoException(PROCEDURE_CALL_FAILED, t);
    }

    return completedFuture(null);
  }
  private InternalTable buildPartitions(
      Session session, String catalogName, Map<String, NullableValue> filters) {
    QualifiedObjectName tableName = extractQualifiedTableName(catalogName, filters);

    InternalTable.Builder table =
        InternalTable.builder(informationSchemaTableColumns(TABLE_INTERNAL_PARTITIONS));

    Optional<TableHandle> tableHandle = metadata.getTableHandle(session, tableName);
    if (!tableHandle.isPresent()) {
      throw new TableNotFoundException(tableName.asSchemaTableName());
    }

    List<TableLayoutResult> layouts =
        metadata.getLayouts(
            session, tableHandle.get(), Constraint.<ColumnHandle>alwaysTrue(), Optional.empty());

    if (layouts.size() == 1) {
      Map<ColumnHandle, String> columnHandles =
          ImmutableBiMap.copyOf(metadata.getColumnHandles(session, tableHandle.get())).inverse();
      Map<ColumnHandle, MethodHandle> methodHandles = new HashMap<>();
      for (ColumnHandle columnHandle : columnHandles.keySet()) {
        try {
          ColumnMetadata columnMetadata =
              metadata.getColumnMetadata(session, tableHandle.get(), columnHandle);
          Signature operator =
              metadata.getFunctionRegistry().getCoercion(columnMetadata.getType(), VARCHAR);
          MethodHandle methodHandle =
              metadata
                  .getFunctionRegistry()
                  .getScalarFunctionImplementation(operator)
                  .getMethodHandle();
          methodHandles.put(columnHandle, methodHandle);
        } catch (OperatorNotFoundException exception) {
          // Do not put the columnHandle in the map.
        }
      }

      TableLayout layout = Iterables.getOnlyElement(layouts).getLayout();
      layout
          .getDiscretePredicates()
          .ifPresent(
              domains -> {
                int partitionNumber = 1;
                for (TupleDomain<ColumnHandle> domain : domains) {
                  for (Entry<ColumnHandle, NullableValue> entry :
                      TupleDomain.extractFixedValues(domain).get().entrySet()) {
                    ColumnHandle columnHandle = entry.getKey();
                    String columnName = columnHandles.get(columnHandle);
                    String value = null;
                    if (entry.getValue().getValue() != null) {
                      if (methodHandles.containsKey(columnHandle)) {
                        try {
                          value =
                              ((Slice)
                                      methodHandles
                                          .get(columnHandle)
                                          .invokeWithArguments(entry.getValue().getValue()))
                                  .toStringUtf8();
                        } catch (Throwable throwable) {
                          throw Throwables.propagate(throwable);
                        }
                      } else {
                        // OperatorNotFoundException was thrown for this columnHandle
                        value = "<UNREPRESENTABLE VALUE>";
                      }
                    }
                    table.add(
                        catalogName,
                        tableName.getSchemaName(),
                        tableName.getObjectName(),
                        partitionNumber,
                        columnName,
                        value);
                  }
                  partitionNumber++;
                }
              });
    }
    return table.build();
  }