/** Basic test of DatabaseMetaData functions that access system tables */
  public void testTwo() throws Exception {

    Connection conn = newConnection();
    int updateCount;

    try {
      TestUtil.testScript(conn, "testrun/hsqldb/TestSelf.txt");

      DatabaseMetaData dbmeta = conn.getMetaData();

      dbmeta.allProceduresAreCallable();
      dbmeta.getBestRowIdentifier(null, null, "T_1", DatabaseMetaData.bestRowTransaction, true);
      dbmeta.getCatalogs();
      dbmeta.getColumnPrivileges(null, "PUBLIC", "T_1", "%");
      dbmeta.getColumns("PUBLIC", "PUBLIC", "T_1", "%");
      dbmeta.getCrossReference(null, null, "T_1", null, null, "T_1");
      dbmeta.getExportedKeys(null, null, "T_1");
      dbmeta.getFunctionColumns(null, "%", "%", "%");
      dbmeta.getFunctions(null, "%", "%");
      dbmeta.getImportedKeys("PUBLIC", "PUBLIC", "T_1");
      dbmeta.getIndexInfo("PUBLIC", "PUBLIC", "T1", true, true);
      dbmeta.getPrimaryKeys("PUBLIC", "PUBLIC", "T_1");
      dbmeta.getProcedureColumns(null, null, "%", "%");
      dbmeta.getProcedures("PUBLIC", "%", "%");
      dbmeta.getSchemas(null, "#");
      dbmeta.getTablePrivileges(null, "%", "%");
      dbmeta.getUDTs(null, "%", "%", new int[] {Types.DISTINCT});

    } catch (Exception e) {
      assertTrue("unable to prepare or execute DDL", false);
    } finally {
      conn.close();
    }
  }
 public ResultSet getExportedKeys(String catalog, String schema, String table)
     throws SQLException {
   _conn.checkOpen();
   try {
     return DelegatingResultSet.wrapResultSet(
         _conn, _meta.getExportedKeys(catalog, schema, table));
   } catch (SQLException e) {
     handleException(e);
     throw new AssertionError();
   }
 }
  @Test
  public void columnOrderOfgetExportedKeys() throws SQLException {

    stat.executeUpdate("create table person (id integer primary key)");
    stat.executeUpdate(
        "create table address (pid integer, name, foreign key(pid) references person(id))");

    ResultSet exportedKeys = meta.getExportedKeys("default", "global", "person");
    assertTrue(exportedKeys.next());
    assertEquals("default", exportedKeys.getString("PKTABLE_CAT"));
    assertEquals("global", exportedKeys.getString("PKTABLE_SCHEM"));
    assertEquals("default", exportedKeys.getString("FKTABLE_CAT"));
    assertEquals("global", exportedKeys.getString("FKTABLE_SCHEM"));
    assertNotNull(exportedKeys.getString("PK_NAME"));
    assertNotNull(exportedKeys.getString("FK_NAME"));

    assertEquals("person", exportedKeys.getString("PKTABLE_NAME"));
    assertEquals("id", exportedKeys.getString("PKCOLUMN_NAME"));
    assertEquals("address", exportedKeys.getString("FKTABLE_NAME"));
    assertEquals("pid", exportedKeys.getString("FKCOLUMN_NAME"));

    exportedKeys.close();

    exportedKeys = meta.getExportedKeys(null, null, "address");
    assertFalse(exportedKeys.next());
    exportedKeys.close();

    // With explicit primary column defined.
    stat.executeUpdate("create table REFERRED (ID integer primary key not null)");
    stat.executeUpdate(
        "create table REFERRING (ID integer, RID integer, constraint fk\r\n foreign\tkey\r\n(RID) references REFERRED(id))");

    exportedKeys = meta.getExportedKeys(null, null, "referred");
    assertEquals("referred", exportedKeys.getString("PKTABLE_NAME"));
    assertEquals("referring", exportedKeys.getString("FKTABLE_NAME"));
    assertEquals("fk", exportedKeys.getString("FK_NAME"));
    exportedKeys.close();
  }
  @Test
  public void numberOfgetExportedKeysCols() throws SQLException {

    stat.executeUpdate("create table parent (id1 integer, id2 integer, primary key(id1, id2))");
    stat.executeUpdate(
        "create table child1 (id1 integer, id2 integer,\r\n foreign\tkey(id1) references parent(id1), foreign key(id2) references parent(id2))");
    stat.executeUpdate(
        "create table child2 (id1 integer, id2 integer, foreign key(id2, id1) references parent(id2, id1))");

    ResultSet exportedKeys = meta.getExportedKeys(null, null, "parent");

    // 1st fk (simple) - child1
    assertTrue(exportedKeys.next());
    assertEquals("parent", exportedKeys.getString("PKTABLE_NAME"));
    assertEquals("id2", exportedKeys.getString("PKCOLUMN_NAME"));
    assertNotNull(exportedKeys.getString("PK_NAME"));
    assertNotNull(exportedKeys.getString("FK_NAME"));
    assertEquals("child1", exportedKeys.getString("FKTABLE_NAME"));
    assertEquals("id2", exportedKeys.getString("FKCOLUMN_NAME"));

    // 2nd fk (simple) - child1
    assertTrue(exportedKeys.next());
    assertEquals("parent", exportedKeys.getString("PKTABLE_NAME"));
    assertEquals("id1", exportedKeys.getString("PKCOLUMN_NAME"));
    assertNotNull(exportedKeys.getString("PK_NAME"));
    assertNotNull(exportedKeys.getString("FK_NAME"));
    assertEquals("child1", exportedKeys.getString("FKTABLE_NAME"));
    assertEquals("id1", exportedKeys.getString("FKCOLUMN_NAME"));

    // 3rd fk (composite) - child2
    assertTrue(exportedKeys.next());
    assertEquals("parent", exportedKeys.getString("PKTABLE_NAME"));
    assertEquals("id2", exportedKeys.getString("PKCOLUMN_NAME"));
    assertNotNull(exportedKeys.getString("PK_NAME"));
    assertNotNull(exportedKeys.getString("FK_NAME"));
    assertEquals("child2", exportedKeys.getString("FKTABLE_NAME"));
    assertEquals("id2", exportedKeys.getString("FKCOLUMN_NAME"));

    assertTrue(exportedKeys.next());
    assertEquals("parent", exportedKeys.getString("PKTABLE_NAME"));
    assertEquals("id1", exportedKeys.getString("PKCOLUMN_NAME"));
    assertNotNull(exportedKeys.getString("PK_NAME"));
    assertNotNull(exportedKeys.getString("FK_NAME"));
    assertEquals("child2", exportedKeys.getString("FKTABLE_NAME"));
    assertEquals("id1", exportedKeys.getString("FKCOLUMN_NAME"));

    assertFalse(exportedKeys.next());

    exportedKeys.close();
  }
  protected DataStore getRawKeyList(TableIdentifier tbl, boolean exported) throws SQLException {
    if (this.dbConnection == null) return null;

    TableIdentifier table = tbl.createCopy();
    table.adjustCase(this.dbConnection);

    DatabaseMetaData meta = this.dbConnection.getSqlConnection().getMetaData();

    cancel = false;
    ResultSet rs;
    if (exported) {
      rs =
          meta.getExportedKeys(
              table.getRawCatalog(), table.getRawSchema(), table.getRawTableName());
    } else {
      rs =
          meta.getImportedKeys(
              table.getRawCatalog(), table.getRawSchema(), table.getRawTableName());
    }
    return processResult(rs);
  }
  private void retrieveForeignKeysUsingDatabaseMetadata(
      final NamedObjectList<MutableTable> allTables) throws SchemaCrawlerSQLException {
    final NamedObjectList<MutableForeignKey> foreignKeys = new NamedObjectList<>();
    for (final MutableTable table : allTables) {
      if (table instanceof View) {
        continue;
      }

      final DatabaseMetaData metaData = getMetaData();
      try (final MetadataResultSet results =
          new MetadataResultSet(
              metaData.getImportedKeys(
                  unquotedName(table.getSchema().getCatalogName()),
                  unquotedName(table.getSchema().getName()),
                  unquotedName(table.getName()))); ) {
        createForeignKeys(results, foreignKeys);
      } catch (final SQLException e) {
        throw new SchemaCrawlerSQLException(
            "Could not retrieve foreign keys for table " + table, e);
      }

      // We need to get exported keys as well, since if only a single
      // table is
      // selected, we have not retrieved it's keys that are imported by
      // other
      // tables.
      try (final MetadataResultSet results =
          new MetadataResultSet(
              metaData.getExportedKeys(
                  unquotedName(table.getSchema().getCatalogName()),
                  unquotedName(table.getSchema().getName()),
                  unquotedName(table.getName()))); ) {
        createForeignKeys(results, foreignKeys);
      } catch (final SQLException e) {
        throw new SchemaCrawlerSQLException(
            "Could not retrieve foreign keys for table " + table, e);
      }
    }
  }
  void retrieveForeignKeys(final MutableTable table) throws SQLException {

    final NamedObjectList<MutableForeignKey> foreignKeys = new NamedObjectList<MutableForeignKey>();
    MetadataResultSet results;

    final DatabaseMetaData metaData = getMetaData();

    results =
        new MetadataResultSet(
            metaData.getImportedKeys(
                unquotedName(table.getSchema().getCatalogName()),
                unquotedName(table.getSchema().getSchemaName()),
                unquotedName(table.getName())));
    createForeignKeys(results, foreignKeys);

    results =
        new MetadataResultSet(
            metaData.getExportedKeys(
                unquotedName(table.getSchema().getCatalogName()),
                unquotedName(table.getSchema().getSchemaName()),
                unquotedName(table.getName())));
    createForeignKeys(results, foreignKeys);
  }
 public void checkForeignKeys(boolean mustExist) throws Exception {
   Connection con = ApiStack.getInterface(Connection.class);
   DatabaseMetaData md = con.getMetaData();
   ResultSet rs = md.getTables(null, null, "%", null);
   boolean found = false;
   while (rs.next()) {
     ResultSet rsKeys = md.getExportedKeys(rs.getString(1), rs.getString(2), rs.getString(3));
     while (rsKeys.next()) {
       trace(
           rsKeys.getString(3)
               + "."
               + rsKeys.getString(4)
               + "<="
               + rsKeys.getString(7)
               + "."
               + rsKeys.getString(8));
       found = true;
     }
   }
   assertTrue(
       "Foreign keys exist = NOT " + mustExist + ", see trace",
       (mustExist && found) || (!mustExist && !found));
 }
 @Test
 public void testExportedKeys() throws Exception {
   TestMMDatabaseMetaData.compareResultSet(
       dbMetadata.getExportedKeys(VDB, null, "%")); // $NON-NLS-1$ //$NON-NLS-2$
 }
  public void testMetaData() {

    String ddl0 =
        "DROP TABLE ADDRESSBOOK IF EXISTS; DROP TABLE ADDRESSBOOK_CATEGORY IF EXISTS; DROP TABLE USER IF EXISTS;";
    String ddl1 =
        "CREATE TABLE USER(USER_ID INTEGER NOT NULL PRIMARY KEY,LOGIN_ID VARCHAR(128) NOT NULL,USER_NAME VARCHAR(254) DEFAULT ' ' NOT NULL,CREATE_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,UPDATE_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,LAST_ACCESS_DATE TIMESTAMP,CONSTRAINT IXUQ_LOGIN_ID0 UNIQUE(LOGIN_ID))";
    String ddl2 =
        "CREATE TABLE ADDRESSBOOK_CATEGORY(USER_ID INTEGER NOT NULL,CATEGORY_ID INTEGER DEFAULT 0 NOT NULL,CATEGORY_NAME VARCHAR(60) DEFAULT '' NOT NULL,CONSTRAINT SYS_PK_ADDRESSBOOK_CATEGORY PRIMARY KEY(USER_ID,CATEGORY_ID),CONSTRAINT FK_ADRBKCAT1 FOREIGN KEY(USER_ID) REFERENCES USER(USER_ID) ON DELETE CASCADE)";
    String ddl3 =
        "CREATE TABLE ADDRESSBOOK(USER_ID INTEGER NOT NULL,ADDRESSBOOK_ID INTEGER NOT NULL,CATEGORY_ID INTEGER DEFAULT 0 NOT NULL,FIRST VARCHAR(64) DEFAULT '' NOT NULL,LAST VARCHAR(64) DEFAULT '' NOT NULL,NOTE VARCHAR(128) DEFAULT '' NOT NULL,CONSTRAINT SYS_PK_ADDRESSBOOK PRIMARY KEY(USER_ID,ADDRESSBOOK_ID),CONSTRAINT FK_ADRBOOK1 FOREIGN KEY(USER_ID,CATEGORY_ID) REFERENCES ADDRESSBOOK_CATEGORY(USER_ID,CATEGORY_ID) ON DELETE CASCADE)";
    String result1 = "1";
    String result2 = "2";
    String result3 = "3";
    String result4 = "4";
    String result5 = "5";

    try {
      stmnt.execute(ddl0);
      stmnt.execute(ddl1);
      stmnt.execute(ddl2);
      stmnt.execute(ddl3);

      DatabaseMetaData md = connection.getMetaData();

      {
        System.out.println("Testing DatabaseMetaData methods");
        System.out.println(md.getDatabaseMajorVersion());
        System.out.println(md.getDatabaseMinorVersion());
        System.out.println(md.getDatabaseProductName());
        System.out.println(md.getDatabaseProductVersion());
        System.out.println(md.getDefaultTransactionIsolation());
        System.out.println(md.getDriverMajorVersion());
        System.out.println(md.getDriverMinorVersion());
        System.out.println(md.getDriverName());
        System.out.println(md.getDriverVersion());
        System.out.println(md.getExtraNameCharacters());
        System.out.println(md.getIdentifierQuoteString());
        System.out.println(md.getJDBCMajorVersion());
        System.out.println(md.getJDBCMinorVersion());
        System.out.println(md.getMaxBinaryLiteralLength());
        System.out.println(md.getMaxCatalogNameLength());
        System.out.println(md.getMaxColumnsInGroupBy());
        System.out.println(md.getMaxColumnsInIndex());
        System.out.println(md.getMaxColumnsInOrderBy());
        System.out.println(md.getMaxColumnsInSelect());
        System.out.println(md.getMaxColumnsInTable());
        System.out.println(md.getMaxConnections());
        System.out.println(md.getMaxCursorNameLength());
        System.out.println(md.getMaxIndexLength());
        System.out.println(md.getMaxProcedureNameLength());
        System.out.println(md.getMaxRowSize());
        System.out.println(md.getMaxSchemaNameLength());
        System.out.println(md.getMaxStatementLength());
        System.out.println(md.getMaxStatements());
        System.out.println(md.getMaxTableNameLength());
        System.out.println(md.getMaxUserNameLength());
        System.out.println(md.getNumericFunctions());
        System.out.println(md.getProcedureTerm());
        System.out.println(md.getResultSetHoldability());
        System.out.println(md.getSchemaTerm());
        System.out.println(md.getSearchStringEscape());
        System.out.println("Testing DatabaseMetaData.getSQLKeywords()");
        System.out.println(md.getSQLKeywords());
        System.out.println(md.getSQLStateType());
        System.out.println("Testing DatabaseMetaData.getStringFunctions()");
        System.out.println(md.getStringFunctions());
        System.out.println("Testing DatabaseMetaData.getSystemFunctions()");
        System.out.println(md.getSystemFunctions());
        System.out.println("Testing DatabaseMetaData.getTimeDateFunctions()");
        System.out.println(md.getTimeDateFunctions());
        System.out.println(md.getURL());
        System.out.println(md.getUserName());
        System.out.println(DatabaseMetaData.importedKeyCascade);
        System.out.println(md.isCatalogAtStart());
        System.out.println(md.isReadOnly());

        ResultSet rs;

        rs = md.getPrimaryKeys(null, null, "USER");

        ResultSetMetaData rsmd = rs.getMetaData();
        String result0 = "";

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result0 += rs.getString(i + 1) + ":";
          }

          result0 += "\n";
        }

        rs.close();
        System.out.println(result0);
      }

      {
        ResultSet rs;

        rs = md.getBestRowIdentifier(null, null, "USER", 0, true);

        ResultSetMetaData rsmd = rs.getMetaData();
        String result0 = "";

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result0 += rs.getString(i + 1) + ":";
          }

          result0 += "\n";
        }

        rs.close();
        System.out.println(result0);
      }

      {
        ResultSet rs = md.getImportedKeys(null, null, "ADDRESSBOOK");
        ResultSetMetaData rsmd = rs.getMetaData();

        result1 = "";

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result1 += rs.getString(i + 1) + ":";
          }

          result1 += "\n";
        }

        rs.close();
        System.out.println(result1);
      }

      {
        ResultSet rs =
            md.getCrossReference(null, null, "ADDRESSBOOK_CATEGORY", null, null, "ADDRESSBOOK");
        ResultSetMetaData rsmd = rs.getMetaData();

        result2 = "";

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result2 += rs.getString(i + 1) + ":";
          }

          result2 += "\n";
        }

        rs.close();
        System.out.println(result2);
      }

      {
        ResultSet rs = md.getExportedKeys(null, null, "USER");
        ResultSetMetaData rsmd = rs.getMetaData();

        result3 = "";

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result3 += rs.getString(i + 1) + ":";
          }

          result3 += "\n";
        }

        rs.close();
        System.out.println(result3);
      }

      {
        ResultSet rs = md.getCrossReference(null, null, "USER", null, null, "ADDRESSBOOK_CATEGORY");
        ResultSetMetaData rsmd = rs.getMetaData();

        result4 = "";

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result4 += rs.getString(i + 1) + ":";
          }

          result4 += "\n";
        }

        rs.close();
        System.out.println(result4);
      }

      {
        stmnt.execute("DROP TABLE T IF EXISTS;");
        stmnt.execute("CREATE TABLE T (I IDENTITY, A CHAR(20), B CHAR(20));");
        stmnt.execute("INSERT INTO T VALUES (NULL, 'get_column_name', '" + getColumnName + "');");

        ResultSet rs = stmnt.executeQuery("SELECT I, A, B, A \"aliasA\", B \"aliasB\", 1 FROM T;");
        ResultSetMetaData rsmd = rs.getMetaData();

        result5 = "";

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result5 += rsmd.getColumnName(i + 1) + ":" + rs.getString(i + 1) + ":";
          }

          result5 += "\n";
        }

        rs.close();

        rs = stmnt.executeQuery("SELECT I, A, B, A \"aliasA\", B \"aliasB\", 1 FROM T;");
        rsmd = rs.getMetaData();

        for (; rs.next(); ) {
          for (int i = 0; i < rsmd.getColumnCount(); i++) {
            result5 += rsmd.getColumnLabel(i + 1) + ":" + rs.getString(i + 1) + ":";
          }

          result5 += "\n";
        }

        System.out.println(result5);
        System.out.println("first column identity: " + rsmd.isAutoIncrement(1));
        rsmd.isCaseSensitive(1);
        rsmd.isCurrency(1);
        rsmd.isDefinitelyWritable(1);
        rsmd.isNullable(1);
        rsmd.isReadOnly(1);
        rsmd.isSearchable(1);
        rsmd.isSigned(1);
        rsmd.isWritable(1);
        rs.close();

        // test identity with PreparedStatement
        pstmnt = connection.prepareStatement("INSERT INTO T VALUES (?,?,?)");

        pstmnt.setString(1, null);
        pstmnt.setString(2, "test");
        pstmnt.setString(3, "test2");
        pstmnt.executeUpdate();

        pstmnt = connection.prepareStatement("call identity()");

        ResultSet rsi = pstmnt.executeQuery();

        rsi.next();

        int identity = rsi.getInt(1);

        System.out.println("call identity(): " + identity);
        rsi.close();
      }
    } catch (SQLException e) {
      fail(e.getMessage());
    }

    System.out.println("testMetaData complete");

    // assert equality of exported and imported with xref
    assertEquals(result1, result2);
    assertEquals(result3, result4);
  }
    public List<RelationData> loadData(IServerInternal server, IProgressMonitor monitor) {
      List<RelationData> relations = new ArrayList<RelationData>();
      try {
        List<String> tableNames = server.getTableAndViewNames(true, true);
        // plus 1 for sorting at the end
        monitor.beginTask("Loading relations", tableNames.size() + 1);
        for (String tableName : tableNames) {
          if (isCanceled()) {
            return null;
          }
          Table table = server.getTable(tableName);
          Connection connection = null;
          ResultSet resultSet = null;
          try {
            connection = server.getConnection();
            DatabaseMetaData dbmd = connection.getMetaData();
            Map<String, List<List<String[]>>> relationInfo =
                new HashMap<String, List<List<String[]>>>();

            resultSet =
                dbmd.getExportedKeys(
                    server.getConfig().getCatalog(),
                    server.getConfig().getSchema(),
                    table.getSQLName());
            while (resultSet.next()) {
              String pcolumnName = resultSet.getString("PKCOLUMN_NAME");
              String ftableName = resultSet.getString("FKTABLE_NAME");
              String fcolumnName = resultSet.getString("FKCOLUMN_NAME");
              String fkname = resultSet.getString("FK_NAME");

              String relname = fkname;
              if (relname == null) relname = table.getSQLName() + "_to_" + ftableName;

              int keySeq = resultSet.getInt("KEY_SEQ");
              Debug.trace(
                  "Found (export) rel: name: "
                      + relname
                      + "  keyseq = "
                      + keySeq
                      + ' '
                      + table.getSQLName()
                      + ' '
                      + pcolumnName
                      + " -> "
                      + ftableName
                      + ' '
                      + fcolumnName);

              List<List<String[]>> rel_items_list = relationInfo.get(relname);
              if (rel_items_list == null) {
                rel_items_list = new ArrayList<List<String[]>>();
                relationInfo.put(relname, rel_items_list);
                rel_items_list.add(new ArrayList<String[]>());
              }
              // rel_items_list is a list of items-lists, we are adding items to the last of this
              // list
              rel_items_list
                  .get(rel_items_list.size() - 1)
                  .add(
                      new String[] {
                        table.getSQLName(), pcolumnName, ftableName, fcolumnName, fkname
                      });
            }
            resultSet = Utils.closeResultSet(resultSet);

            resultSet =
                dbmd.getImportedKeys(
                    server.getConfig().getCatalog(),
                    server.getConfig().getSchema(),
                    table.getSQLName());
            int lastKeySeq = Integer.MAX_VALUE;
            List<List<String[]>> fk_rel_items_list = new ArrayList<List<String[]>>();
            while (resultSet.next()) {
              String pcolumnName = resultSet.getString("PKCOLUMN_NAME");
              String ptableName = resultSet.getString("PKTABLE_NAME");
              String fcolumnName = resultSet.getString("FKCOLUMN_NAME");

              int keySeq = resultSet.getInt("KEY_SEQ");
              Debug.trace(
                  "Found (import) rel: name: "
                      + table.getSQLName()
                      + "_to_"
                      + ptableName
                      + " keyseq = "
                      + keySeq
                      + ' '
                      + table.getSQLName()
                      + ' '
                      + pcolumnName
                      + " -> "
                      + ptableName
                      + ' '
                      + fcolumnName);

              // assume KEY_SEQ ascending ordered, do not assume 0 or 1 based (jdbc spec is not
              // clear on this).
              // when KEY_SEQ is not increasing, we have a separate constraint between the same
              // tables.
              if (fk_rel_items_list.size() == 0 || keySeq <= lastKeySeq) {
                fk_rel_items_list.add(new ArrayList<String[]>());
              }
              lastKeySeq = keySeq;

              // add the item to the last list of rel_items_list
              fk_rel_items_list
                  .get(fk_rel_items_list.size() - 1)
                  .add(
                      new String[] {
                        table.getSQLName(), fcolumnName, ptableName, pcolumnName, null
                      });
            }

            // generate relation names for the inversed fk constraints
            for (List<String[]> rel_items_list : fk_rel_items_list) {
              String relationName = createInversedFKRelationName(table, rel_items_list);
              List<List<String[]>> rel_items = relationInfo.get(relationName);
              if (rel_items == null) {
                relationInfo.put(relationName, rel_items = new ArrayList<List<String[]>>());
              }
              rel_items.add(rel_items_list);
            }
            resultSet = Utils.closeResultSet(resultSet);

            for (Map.Entry<String, List<List<String[]>>> entry : relationInfo.entrySet()) {
              String rname = entry.getKey();
              List<List<String[]>> rel_items_list = entry.getValue();
              // we may have multiple lists of items defined for the same relation name
              for (int l = 0; l < rel_items_list.size(); l++) {
                List<Column> primaryColumns = new ArrayList<Column>();
                List<Column> foreignColumns = new ArrayList<Column>();

                for (String[] element : rel_items_list.get(l)) {
                  //									String ptableName = element[0];
                  String pcolumnName = element[1];
                  String ftableName = element[2];
                  String fcolumnName = element[3];
                  //									String fkname = element[4];

                  Table foreignTable = server.getTable(ftableName);
                  if (foreignTable == null || foreignTable.isMarkedAsHiddenInDeveloper()) continue;

                  Column primaryColumn = table.getColumn(pcolumnName);
                  Column foreignColumn = foreignTable.getColumn(fcolumnName);

                  if (primaryColumn == null || foreignColumn == null) continue;
                  primaryColumns.add(primaryColumn);
                  foreignColumns.add(foreignColumn);
                }

                if (primaryColumns.size() != 0) {
                  // postfix the relation name when there are multiple
                  String relationName = rname;
                  if (rel_items_list.size() > 1) {
                    relationName += "_" + (l + 1);
                  }

                  boolean defaultAdd =
                      ServoyModelManager.getServoyModelManager()
                              .getServoyModel()
                              .getFlattenedSolution()
                              .getRelation(relationName)
                          == null;

                  relations.add(
                      new RelationData(
                          relationName, table, primaryColumns, foreignColumns, defaultAdd));
                }
              }
            }
          } catch (RepositoryException e) {
            ServoyLog.logError(e);
          } catch (SQLException e) {
            ServoyLog.logError(e);
          } finally {
            Utils.closeResultSet(resultSet);
            Utils.closeConnection(connection);
          }
          monitor.worked(1);
        }
        monitor.done();
      } catch (RepositoryException ex) {
        ServoyLog.logError(ex);
      }
      return relations;
    }
 public ResultSet getExportedKeys(String catalog, String schema, String table)
     throws SQLException {
   return throwExceptionDelegate.getExportedKeys(catalog, schema, table);
 }