static void resolveTables(
      DBRProgressMonitor monitor,
      DBCExecutionContext executionContext,
      TemplateContext context,
      List<DBSEntity> entities)
      throws DBException {
    TemplateVariable schemaVariable =
        ((SQLContext) context).getTemplateVariable(SQLContainerResolver.VAR_NAME_SCHEMA);
    TemplateVariable catalogVariable =
        ((SQLContext) context).getTemplateVariable(SQLContainerResolver.VAR_NAME_CATALOG);

    String catalogName = catalogVariable == null ? null : catalogVariable.getDefaultValue();
    String schemaName = schemaVariable == null ? null : schemaVariable.getDefaultValue();
    DBSObjectContainer objectContainer =
        DBUtils.getAdapter(DBSObjectContainer.class, executionContext.getDataSource());
    if (objectContainer == null) {
      return;
    }
    if (!CommonUtils.isEmpty(catalogName) || !CommonUtils.isEmpty(schemaName)) {
      // Find container for specified schema/catalog
      objectContainer =
          (DBSObjectContainer)
              DBUtils.getObjectByPath(monitor, objectContainer, catalogName, schemaName, null);
    } else {
      DBSObjectSelector objectSelector =
          DBUtils.getAdapter(DBSObjectSelector.class, executionContext.getDataSource());
      if (objectSelector != null) {
        objectContainer =
            DBUtils.getAdapter(DBSObjectContainer.class, objectSelector.getSelectedObject());
      }
    }
    if (objectContainer != null) {
      makeProposalsFromChildren(monitor, objectContainer, entities);
    }
  }
  private SQLCompletionProposal makeProposalsFromObject(
      DBPNamedObject object, @Nullable DBPImage objectIcon) {
    String objectName = DBUtils.getObjectFullName(object);

    StringBuilder info = new StringBuilder();
    PropertyCollector collector = new PropertyCollector(object, false);
    collector.collectProperties();
    for (DBPPropertyDescriptor descriptor : collector.getPropertyDescriptors2()) {
      Object propValue = collector.getPropertyValue(descriptor.getId());
      if (propValue == null) {
        continue;
      }
      String propString = propValue.toString();
      info.append("<b>").append(descriptor.getDisplayName()).append(":  </b>");
      info.append(propString);
      info.append("<br>");
    }

    boolean isSingleObject = true;
    String replaceString = null;
    DBPDataSource dataSource = editor.getDataSource();
    if (dataSource != null) {
      // If we replace short name with referenced object
      // and current active schema (catalog) is not this object's container then
      // replace with full qualified name
      if (!getPreferences().getBoolean(SQLPreferenceConstants.PROPOSAL_SHORT_NAME)
          && object instanceof DBSObjectReference) {
        if (wordDetector.getFullWord().indexOf(editor.getSyntaxManager().getStructSeparator())
            == -1) {
          DBSObjectReference structObject = (DBSObjectReference) object;
          if (structObject.getContainer() != null) {
            DBSObject selectedObject = getSelectedObject(dataSource);
            if (selectedObject != structObject.getContainer()) {
              replaceString =
                  DBUtils.getFullQualifiedName(dataSource, structObject.getContainer(), object);
              isSingleObject = false;
            }
          }
        }
      }
      if (replaceString == null) {
        replaceString = DBUtils.getQuotedIdentifier(dataSource, object.getName());
      }
    } else {
      replaceString = DBUtils.getObjectShortName(object);
    }
    return createCompletionProposal(
        replaceString, objectName, info.toString(), objectIcon, isSingleObject, object);
  }
Example #3
0
  @Override
  public List<GenericSequence> loadSequences(
      @NotNull DBRProgressMonitor monitor, @NotNull GenericStructContainer container)
      throws DBException {
    try (JDBCSession session =
        DBUtils.openMetaSession(monitor, container.getDataSource(), "Read sequences")) {
      try (JDBCPreparedStatement dbStat =
          session.prepareStatement("SELECT * FROM INFORMATION_SCHEMA.SEQUENCES")) {
        List<GenericSequence> result = new ArrayList<>();

        try (JDBCResultSet dbResult = dbStat.executeQuery()) {
          while (dbResult.next()) {
            String name = JDBCUtils.safeGetString(dbResult, "SEQUENCE_NAME");
            if (name == null) {
              continue;
            }
            String description = JDBCUtils.safeGetString(dbResult, "REMARKS");
            GenericSequence sequence =
                new GenericSequence(
                    container,
                    name,
                    description,
                    JDBCUtils.safeGetLong(dbResult, "CURRENT_VALUE"),
                    JDBCUtils.safeGetLong(dbResult, "MIN_VALUE"),
                    JDBCUtils.safeGetLong(dbResult, "MAX_VALUE"),
                    JDBCUtils.safeGetLong(dbResult, "INCREMENT"));
            result.add(sequence);
          }
        }
        return result;
      }
    } catch (SQLException e) {
      throw new DBException(e, container.getDataSource());
    }
  }
 void updateMappingType(DBRProgressMonitor monitor) throws DBException {
   switch (parent.getMappingType()) {
     case existing:
       {
         mappingType = DatabaseMappingType.unspecified;
         if (parent.getTarget() instanceof DBSEntity) {
           if (CommonUtils.isEmpty(targetName)) {
             targetName = source.getName();
           }
           target =
               DBUtils.findObject(
                   ((DBSEntity) parent.getTarget()).getAttributes(monitor), targetName);
           if (target != null) {
             mappingType = DatabaseMappingType.existing;
           } else {
             mappingType = DatabaseMappingType.create;
           }
         }
         break;
       }
     case create:
       mappingType = DatabaseMappingType.create;
       if (CommonUtils.isEmpty(targetName)) {
         targetName = source.getName();
       }
       break;
     case skip:
       mappingType = DatabaseMappingType.skip;
       break;
     default:
       mappingType = DatabaseMappingType.unspecified;
       break;
   }
 }
 /**
  * Sets entity attribute
  *
  * @return true if attribute type differs from meta attribute type.
  */
 public boolean setEntityAttribute(@Nullable DBSEntityAttribute entityAttribute) {
   this.entityAttribute = entityAttribute;
   if (entityAttribute != null && !haveEqualsTypes(metaAttribute, entityAttribute)) {
     valueHandler = DBUtils.findValueHandler(getDataSource(), entityAttribute);
     return true;
   }
   return false;
 }
 @Nullable
 private static DBSObject getSelectedObject(DBPDataSource dataSource) {
   DBSObjectSelector objectSelector = DBUtils.getAdapter(DBSObjectSelector.class, dataSource);
   if (objectSelector != null) {
     return objectSelector.getSelectedObject();
   }
   return null;
 }
 @Override
 public void lateBinding(@NotNull DBCSession session, List<Object[]> rows) throws DBException {
   DBSEntityAttribute entityAttribute = getEntityAttribute();
   if (entityAttribute != null) {
     referrers = DBUtils.getAttributeReferrers(session.getProgressMonitor(), entityAttribute);
   }
   super.lateBinding(session, rows);
 }
Example #8
0
 private static boolean equalObjects(DBSObject object1, DBSObject object2) {
   if (object1 == object2) {
     return true;
   }
   if (object1 == null || object2 == null) {
     return false;
   }
   while (object1 != null && object2 != null) {
     if (object1.getClass() != object2.getClass()
         || !CommonUtils.equalObjects(
             DBUtils.getObjectUniqueName(object1), DBUtils.getObjectUniqueName(object2))) {
       return false;
     }
     object1 = object1.getParentObject();
     object2 = object2.getParentObject();
   }
   return true;
 }
  public String getTargetType(DBPDataSource targetDataSource) {
    if (!CommonUtils.isEmpty(targetType)) {
      return targetType;
    }
    // TODO: make some smart data type matcher
    // Current solution looks like hack
    String typeName = source.getTypeName();
    DBPDataKind dataKind = source.getDataKind();
    if (targetDataSource instanceof DBPDataTypeProvider) {
      DBPDataTypeProvider dataTypeProvider = (DBPDataTypeProvider) targetDataSource;
      DBSDataType dataType = dataTypeProvider.getLocalDataType(typeName);
      if (dataType == null && typeName.equals("DOUBLE")) {
        dataType = dataTypeProvider.getLocalDataType("DOUBLE PRECISION");
        if (dataType != null) {
          typeName = dataType.getTypeName();
        }
      }
      if (dataType != null && dataType.getDataKind() != dataKind) {
        // Type mismatch
        dataType = null;
      }
      if (dataType == null) {
        // Type not supported by target database
        // Let's try to find something similar
        List<DBSDataType> possibleTypes = new ArrayList<>();
        for (DBSDataType type : dataTypeProvider.getLocalDataTypes()) {
          if (type.getDataKind() == dataKind) {
            possibleTypes.add(type);
          }
        }
        typeName = DBUtils.getDefaultDataTypeName(targetDataSource, dataKind);
        if (!possibleTypes.isEmpty()) {
          DBSDataType targetType = null;
          for (DBSDataType type : possibleTypes) {
            if (type.getName().equalsIgnoreCase(typeName)) {
              targetType = type;
              break;
            }
          }
          if (targetType == null) {
            targetType = possibleTypes.get(0);
          }
          typeName = targetType.getTypeName();
        }
      }
      if (dataType != null) {
        dataKind = dataType.getDataKind();
      }
    }

    String modifiers = SQLUtils.getColumnTypeModifiers(source, typeName, dataKind);
    if (modifiers != null) {
      typeName += modifiers;
    }
    return typeName;
  }
 @NotNull
 @Override
 public String getColumnId() {
   DBCExecutionContext context = getExecutionContext();
   DBCAttributeMetaData metaAttribute = binding.getMetaAttribute();
   return DBUtils.getSimpleQualifiedName(
       context == null ? null : context.getDataSource().getContainer().getName(),
       metaAttribute.getEntityName(),
       metaAttribute.getName());
 }
Example #11
0
 void setSearchPath(DBRProgressMonitor monitor, PostgreSchema schema, JDBCExecutionContext context)
     throws DBCException {
   try (JDBCSession session =
       context.openSession(monitor, DBCExecutionPurpose.UTIL, "Change search path")) {
     JDBCUtils.executeSQL(
         session, "SET search_path = \"$user\"," + DBUtils.getQuotedIdentifier(schema));
   } catch (SQLException e) {
     throw new DBCException("Error setting search path", e, dataSource);
   }
 }
  /*
   * Turns the vector into an Array of ICompletionProposal objects
   */
  protected SQLCompletionProposal createCompletionProposal(
      String replaceString,
      String displayString,
      String description,
      @Nullable DBPImage image,
      boolean isObject,
      @Nullable DBPNamedObject object) {
    DBPPreferenceStore store = getPreferences();
    DBPDataSource dataSource = editor.getDataSource();
    if (dataSource != null) {
      if (isObject) {
        // Escape replace string if required
        replaceString = DBUtils.getQuotedIdentifier(dataSource, replaceString);
      }
    }

    // If we have quoted string then ignore pref settings
    boolean quotedString = wordDetector.isQuoted(replaceString);
    final int proposalCase =
        quotedString
            ? SQLPreferenceConstants.PROPOSAL_CASE_DEFAULT
            : store.getInt(SQLPreferenceConstants.PROPOSAL_INSERT_CASE);
    switch (proposalCase) {
      case SQLPreferenceConstants.PROPOSAL_CASE_UPPER:
        replaceString = replaceString.toUpperCase();
        break;
      case SQLPreferenceConstants.PROPOSAL_CASE_LOWER:
        replaceString = replaceString.toLowerCase();
        break;
      default:
        DBPIdentifierCase convertCase =
            quotedString && dataSource instanceof SQLDataSource
                ? ((SQLDataSource) dataSource).getSQLDialect().storesQuotedCase()
                : DBPIdentifierCase.MIXED;
        replaceString = convertCase.transform(replaceString);
        break;
    }

    Image img = image == null ? null : DBeaverIcons.getImage(image);
    return new SQLCompletionProposal(
        editor.getSyntaxManager(),
        displayString,
        replaceString, // replacementString
        wordDetector, // wordDetector
        replaceString.length(), // cursorPosition the position of the cursor following the insert
        // relative to replacementOffset
        img, // image to display
        new ContextInformation(
            img,
            displayString,
            displayString), // the context information associated with this proposal
        description,
        object);
  }
Example #13
0
  @Override
  public void setDefaultObject(@NotNull DBRProgressMonitor monitor, @NotNull DBSObject object)
      throws DBException {
    if (object instanceof PostgreSchema) {
      PostgreSchema oldActive = getDefaultObject();
      if (oldActive == object) {
        return;
      }

      for (JDBCExecutionContext context : dataSource.getAllContexts()) {
        setSearchPath(monitor, (PostgreSchema) object, context);
      }
      dataSource.setActiveSchemaName(object.getName());
      dataSource.setSearchPath(object.getName());

      if (oldActive != null) {
        DBUtils.fireObjectSelect(oldActive, false);
      }
      DBUtils.fireObjectSelect(object, true);
    }
  }
Example #14
0
 private Object createXmlObject(JDBCSession session, InputStream stream) throws DBCException {
   try {
     return BeanUtils.invokeStaticMethod(
         DBUtils.getDriverClass(dataSource, OracleConstants.XMLTYPE_CLASS_NAME),
         "createXML",
         new Class[] {java.sql.Connection.class, java.io.InputStream.class},
         new Object[] {session.getOriginal(), stream});
   } catch (SQLException e) {
     throw new DBCException(e, session.getDataSource());
   } catch (Throwable e) {
     throw new DBCException("Internal error when creating XMLType", e, session.getDataSource());
   }
 }
 public boolean appliesTo(DBPObject object, Object context) {
   object = DBUtils.getPublicObject(object);
   if (object == null) {
     return false;
   }
   Object adapted = adaptType(object);
   for (ObjectType objectType : objectTypes) {
     if (objectType.appliesTo(object, context)
         || (adapted != null && objectType.appliesTo(adapted, context))) {
       return true;
     }
   }
   return false;
 }
 @Override
 protected DBEPersistAction[] makeObjectDeleteActions(ObjectDeleteCommand command) {
   return new DBEPersistAction[] {
     new SQLDatabasePersistAction(
         ModelMessages.model_jdbc_drop_table_column,
         "ALTER TABLE "
             + command.getObject().getTable().getFullQualifiedName()
             + //$NON-NLS-2$
             " DROP "
             + (hasDDLFeature(command.getObject(), DDL_FEATURE_OMIT_COLUMN_CLAUSE_IN_DROP)
                 ? ""
                 : "COLUMN ")
             + DBUtils.getQuotedIdentifier(
                 command.getObject())) // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
   };
 }
Example #17
0
  public static boolean compileUnit(
      DBRProgressMonitor monitor, DBCCompileLog compileLog, OracleSourceObject unit)
      throws DBCException {
    final DBEPersistAction[] compileActions = unit.getCompileActions();
    if (ArrayUtils.isEmpty(compileActions)) {
      return true;
    }

    try (JDBCSession session =
        DBUtils.openUtilSession(
            monitor, unit.getDataSource(), "Compile '" + unit.getName() + "'")) {
      boolean success = true;
      for (DBEPersistAction action : compileActions) {
        final String script = action.getScript();
        compileLog.trace(script);

        if (monitor.isCanceled()) {
          break;
        }
        try {
          try (DBCStatement dbStat =
              session.prepareStatement(DBCStatementType.QUERY, script, false, false, false)) {
            dbStat.executeStatement();
          }
          action.handleExecute(null);
        } catch (DBCException e) {
          action.handleExecute(e);
          throw e;
        }
        if (action instanceof OracleObjectPersistAction) {
          if (!logObjectErrors(
              session, compileLog, unit, ((OracleObjectPersistAction) action).getObjectType())) {
            success = false;
          }
        }
      }
      final DBSObjectState oldState = unit.getObjectState();
      unit.refreshObjectState(monitor);
      if (unit.getObjectState() != oldState) {
        unit.getDataSource()
            .getContainer()
            .fireEvent(new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, unit));
      }

      return success;
    }
  }
 @Override
 public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
   if (!(receiver instanceof SQLEditorBase)) {
     return false;
   }
   SQLEditor editor = (SQLEditor) receiver;
   final Control editorControl = editor.getEditorControl();
   if (editorControl == null) {
     return false;
   }
   boolean isFocused = editorControl.isFocusControl();
   boolean isConnected =
       editor.getDataSourceContainer() != null && editor.getDataSourceContainer().isConnected();
   switch (property) {
     case PROP_CAN_EXECUTE:
       return isConnected
           && isFocused
           && (!"statement".equals(expectedValue) || editor.hasActiveQuery());
     case PROP_CAN_EXPLAIN:
       return isConnected
           && isFocused
           && editor.hasActiveQuery()
           && DBUtils.getAdapter(DBCQueryPlanner.class, editor.getDataSource()) != null;
     case PROP_CAN_NAVIGATE:
       {
         // Check whether some word is under cursor
         ISelectionProvider selectionProvider = editor.getSelectionProvider();
         if (selectionProvider == null) {
           return false;
         }
         ITextSelection selection = (ITextSelection) selectionProvider.getSelection();
         Document document = editor.getDocument();
         return selection != null
             && document != null
             && !new SQLIdentifierDetector(
                     editor.getSyntaxManager().getStructSeparator(),
                     editor.getSyntaxManager().getQuoteSymbol())
                 .detectIdentifier(
                     document, new Region(selection.getOffset(), selection.getLength()))
                 .isEmpty();
       }
     case PROP_CAN_EXPORT:
       return isConnected && editor.hasActiveQuery();
   }
   return false;
 }
 @Override
 public String getTargetName() {
   switch (mappingType) {
     case existing:
       if (target != null) {
         return DBUtils.getObjectFullName(target, DBPEvaluationContext.UI);
       } else {
         return targetName;
       }
     case create:
       return targetName;
     case skip:
       return TARGET_NAME_SKIP;
     default:
       return "?";
   }
 }
Example #20
0
  public static boolean showDatabaseError(
      Shell shell, String title, String message, DBException error) {
    DBPDataSource dataSource = error.getDataSource();
    DBPErrorAssistant errorAssistant = DBUtils.getAdapter(DBPErrorAssistant.class, dataSource);
    if (errorAssistant != null) {
      DBPErrorAssistant.ErrorType errorType =
          ((DBPErrorAssistant) dataSource).discoverErrorType(error);
      switch (errorType) {
        case CONNECTION_LOST:
          DataSourceInvalidateHandler.showConnectionLostDialog(shell, message, error);
          return true;
        case DRIVER_CLASS_MISSING:
          DriverEditDialog.showBadConfigDialog(shell, message, error);
          return true;
      }
    }

    return false;
  }
  @Override
  protected StringBuilder getNestedDeclaration(
      TABLE_TYPE owner, DBECommandAbstract<OBJECT_TYPE> command) {
    OBJECT_TYPE column = command.getObject();

    // Create column
    String columnName = DBUtils.getQuotedIdentifier(column.getDataSource(), column.getName());

    if (command instanceof SQLObjectEditor.ObjectRenameCommand) {
      columnName = ((ObjectRenameCommand) command).getNewName();
    }

    StringBuilder decl = new StringBuilder(40);
    decl.append(columnName);
    for (ColumnModifier modifier : getSupportedModifiers()) {
      modifier.appendModifier(column, decl, command);
    }

    return decl;
  }
Example #22
0
 @Override
 public String getViewDDL(DBRProgressMonitor monitor, GenericTable sourceObject)
     throws DBException {
   GenericDataSource dataSource = sourceObject.getDataSource();
   try (JDBCSession session =
       DBUtils.openMetaSession(monitor, dataSource, "Read H2 view source")) {
     try (JDBCPreparedStatement dbStat =
         session.prepareStatement(
             "SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS "
                 + "WHERE TABLE_SCHEMA=? AND TABLE_NAME=?")) {
       dbStat.setString(1, sourceObject.getContainer().getName());
       dbStat.setString(2, sourceObject.getName());
       try (JDBCResultSet dbResult = dbStat.executeQuery()) {
         if (dbResult.nextRow()) {
           return dbResult.getString(1);
         }
         return "-- H2 view definition not found";
       }
     }
   } catch (SQLException e) {
     throw new DBException(e, dataSource);
   }
 }
  @Override
  protected String[] resolveAll(final TemplateContext context) {
    final DBCExecutionContext executionContext =
        ((DBPContextProvider) context).getExecutionContext();
    if (executionContext == null) {
      return super.resolveAll(context);
    }

    DBPDataTypeProvider dataTypeProvider =
        DBUtils.getAdapter(DBPDataTypeProvider.class, executionContext.getDataSource());
    if (dataTypeProvider != null) {
      final Collection<? extends DBSDataType> localDataTypes = dataTypeProvider.getLocalDataTypes();
      if (!CommonUtils.isEmpty(localDataTypes)) {
        String[] result = new String[localDataTypes.size()];
        int index = 0;
        for (DBSDataType dataType : localDataTypes) {
          result[index++] = dataType.getName();
        }
        return result;
      }
    }
    return super.resolveAll(context);
  }
  public void generateDiagramObjects(
      DBRProgressMonitor monitor, Collection<? extends DBSObject> roots) throws DBException {
    boolean showViews =
        ERDActivator.getDefault()
            .getPreferenceStore()
            .getBoolean(ERDConstants.PREF_DIAGRAM_SHOW_VIEWS);
    Collection<DBSEntity> tables = collectTables(monitor, roots);
    for (DBSEntity table : tables) {
      if (DBUtils.isHiddenObject(table)) {
        // Skip hidden tables
        continue;
      }
      if (!showViews && table instanceof DBSTable && ((DBSTable) table).isView()) {
        // Skip views
        continue;
      }
      addDiagramEntity(monitor, table);
    }

    // Add new relations
    for (ERDEntity erdEntity : erdEntities) {
      erdEntity.addRelations(monitor, tableMap, false);
    }
  }
  @Override
  public void fetchStart(
      DBCSession session, final DBCResultSet resultSet, long offset, long maxRows)
      throws DBCException {
    this.rows.clear();
    this.offset = offset;
    this.maxRows = maxRows;

    if (!nextSegmentRead) {
      // Get columns metadata
      DBCResultSetMetaData metaData = resultSet.getMeta();

      List<DBCAttributeMetaData> rsAttributes = metaData.getAttributes();
      columnsCount = rsAttributes.size();

      // Extract column info
      metaColumns = new DBDAttributeBindingMeta[columnsCount];
      for (int i = 0; i < columnsCount; i++) {
        metaColumns[i] = DBUtils.getAttributeBinding(session, rsAttributes.get(i));
      }

      resultSetViewer.setMetaData(metaColumns);
    }
  }
 public DBDAttributeBindingMeta(
     @NotNull DBPDataSource dataSource, @NotNull DBCAttributeMetaData metaAttribute) {
   super(DBUtils.findValueHandler(dataSource, metaAttribute));
   this.dataSource = dataSource;
   this.metaAttribute = metaAttribute;
 }
Example #27
0
 @Override
 public String getFullTypeName() {
   return DBUtils.getFullTypeName(this);
 }
 public DBDAttributeBindingMeta(
     @NotNull DBCSession session, @NotNull DBCAttributeMetaData metaAttribute) {
   super(DBUtils.findValueHandler(session, metaAttribute));
   this.dataSource = session.getDataSource();
   this.metaAttribute = metaAttribute;
 }
  @Nullable
  private DBSObject getTableFromAlias(
      DBRProgressMonitor monitor, DBSObjectContainer sc, @Nullable String token) {
    final DBPDataSource dataSource = editor.getDataSource();
    if (!(dataSource instanceof SQLDataSource)) {
      return null;
    }
    if (activeQuery == null) {
      activeQuery = editor.extractQueryAtPos(documentOffset).getQuery() + " ";
    }

    final List<String> nameList = new ArrayList<>();
    if (token == null) {
      token = "";
    }

    {
      Matcher matcher;
      Pattern aliasPattern;
      SQLDialect sqlDialect = ((SQLDataSource) dataSource).getSQLDialect();
      String quoteString = sqlDialect.getIdentifierQuoteString();
      String quote =
          quoteString == null
              ? SQLConstants.STR_QUOTE_DOUBLE
              : SQLConstants.STR_QUOTE_DOUBLE.equals(quoteString)
                  ? quoteString
                  : Pattern.quote(quoteString);
      String catalogSeparator = sqlDialect.getCatalogSeparator();
      while (token.endsWith(catalogSeparator)) token = token.substring(0, token.length() - 1);

      String tableNamePattern =
          "((?:"
              + quote
              + "(?:[.[^"
              + quote
              + "]]+)"
              + quote
              + ")|(?:[\\w"
              + Pattern.quote(catalogSeparator)
              + "]+))";
      String structNamePattern;
      if (CommonUtils.isEmpty(token)) {
        structNamePattern = "(?:from|update|join|into)\\s*" + tableNamePattern;
      } else {
        structNamePattern =
            tableNamePattern
                + "(?:\\s*\\.\\s*"
                + tableNamePattern
                + ")?"
                + "\\s+(?:(?:AS)\\s)?"
                + token
                + "[\\s,]+";
      }

      try {
        aliasPattern = Pattern.compile(structNamePattern, Pattern.CASE_INSENSITIVE);
      } catch (PatternSyntaxException e) {
        // Bad pattern - seems to be a bad token
        return null;
      }
      matcher = aliasPattern.matcher(activeQuery);
      if (!matcher.find()) {
        return null;
      }

      int groupCount = matcher.groupCount();
      for (int i = 1; i <= groupCount; i++) {
        String group = matcher.group(i);
        if (!CommonUtils.isEmpty(group)) {
          String[] allNames = group.split(Pattern.quote(catalogSeparator));
          for (String name : allNames) {
            if (quoteString != null && name.startsWith(quoteString) && name.endsWith(quoteString)) {
              name = name.substring(1, name.length() - 1);
            }
            nameList.add(name);
          }
        }
      }
    }

    if (nameList.isEmpty()) {
      return null;
    }

    for (int i = 0; i < nameList.size(); i++) {
      nameList.set(
          i, DBObjectNameCaseTransformer.transformName(sc.getDataSource(), nameList.get(i)));
    }

    try {
      DBSObject childObject = null;
      while (childObject == null) {
        childObject = DBUtils.findNestedObject(monitor, sc, nameList);
        if (childObject == null) {
          DBSObjectContainer parentSc = DBUtils.getParentAdapter(DBSObjectContainer.class, sc);
          if (parentSc == null) {
            break;
          }
          sc = parentSc;
        }
      }
      if (childObject == null && nameList.size() <= 1) {
        // No such object found - may be it's start of table name
        DBSStructureAssistant structureAssistant =
            DBUtils.getAdapter(DBSStructureAssistant.class, sc);
        if (structureAssistant != null) {
          String objectNameMask = nameList.get(0);
          Collection<DBSObjectReference> tables =
              structureAssistant.findObjectsByMask(
                  monitor,
                  sc,
                  structureAssistant.getAutoCompleteObjectTypes(),
                  wordDetector.removeQuotes(objectNameMask),
                  wordDetector.isQuoted(objectNameMask),
                  2);
          if (!tables.isEmpty()) {
            return tables.iterator().next().resolveObject(monitor);
          }
        }
        return null;
      } else {
        return childObject;
      }
    } catch (DBException e) {
      log.error(e);
      return null;
    }
  }
  private void makeStructureProposals(
      DBRProgressMonitor monitor, DBPDataSource dataSource, List<SQLCompletionProposal> proposals) {
    final DBSObjectContainer rootContainer =
        DBUtils.getAdapter(DBSObjectContainer.class, dataSource);
    if (rootContainer == null) {
      return;
    }
    DBSObjectContainer selectedContainer = null;
    {
      DBSObject selectedObject = getSelectedObject(dataSource);
      if (selectedObject != null) {
        selectedContainer = DBUtils.getAdapter(DBSObjectContainer.class, selectedObject);
      }
    }

    DBSObjectContainer sc = rootContainer;
    DBSObject childObject = sc;
    List<String> tokens = wordDetector.splitWordPart();

    String lastToken = null;
    for (int i = 0; i < tokens.size(); i++) {
      String token = tokens.get(i);
      if (i == tokens.size() - 1 && !wordDetector.getWordPart().endsWith(".")) {
        lastToken = token;
        break;
      }
      if (sc == null) {
        break;
      }
      // Get next structure container
      try {
        String objectName = DBObjectNameCaseTransformer.transformName(dataSource, token);
        childObject = sc.getChild(monitor, objectName);
        if (childObject == null && i == 0 && selectedContainer != null) {
          // Probably it is from selected object, let's try it
          childObject = selectedContainer.getChild(monitor, objectName);
          if (childObject != null) {
            sc = selectedContainer;
          }
        }
        if (childObject == null) {
          if (i == 0) {
            // Assume it's a table alias ?
            childObject = this.getTableFromAlias(monitor, sc, token);
            if (childObject == null) {
              DBSStructureAssistant structureAssistant =
                  DBUtils.getAdapter(DBSStructureAssistant.class, sc);
              if (structureAssistant != null) {
                Collection<DBSObjectReference> references =
                    structureAssistant.findObjectsByMask(
                        monitor,
                        null,
                        structureAssistant.getAutoCompleteObjectTypes(),
                        wordDetector.removeQuotes(token),
                        wordDetector.isQuoted(token),
                        2);
                if (!references.isEmpty()) {
                  childObject = references.iterator().next().resolveObject(monitor);
                }
              }
            }
          } else {
            // Path element not found. Damn - can't do anything.
            return;
          }
        }

        if (childObject instanceof DBSObjectContainer) {
          sc = (DBSObjectContainer) childObject;
        } else {
          sc = null;
        }
      } catch (DBException e) {
        log.error(e);
        return;
      }
    }
    if (childObject == null) {
      return;
    }
    if (lastToken == null) {
      // Get all children objects as proposals
      makeProposalsFromChildren(monitor, childObject, null, proposals);
    } else {
      // Get matched children
      makeProposalsFromChildren(monitor, childObject, lastToken, proposals);
      if (proposals.isEmpty() || tokens.size() == 1) {
        // At last - try to find child tables by pattern
        DBSStructureAssistant structureAssistant = null;
        for (DBSObject object = childObject; object != null; object = object.getParentObject()) {
          structureAssistant = DBUtils.getAdapter(DBSStructureAssistant.class, object);
          if (structureAssistant != null) {
            break;
          }
        }
        if (structureAssistant != null) {
          makeProposalsFromAssistant(monitor, structureAssistant, sc, lastToken, proposals);
        }
      }
    }
  }