static String replaceJdbcMetadataStatement()

in src/main/java/com/google/cloud/spanner/pgadapter/statements/JdbcMetadataStatementHelper.java [43:209]


  static String replaceJdbcMetadataStatement(String sql) {
    // First we look for a number of fixed query prefixes for queries that are completely replaced
    // with Spangres-compatible queries.
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_PREFIX)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_42_0_PREFIX)) {
      return replaceImportedExportedKeysQuery(
          sql, PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_REPLACEMENT, "KEY_SEQ");
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_PREFIX_V42_7_5)) {
      return replaceImportedExportedKeysQuery(
          sql, PgJdbcCatalog.PG_JDBC_EXPORTED_IMPORTED_KEYS_REPLACEMENT_UPPER_CASE, "\"KEY_SEQ\"");
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_PREFIX)) {
      return replaceGetSchemasQuery(sql, PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_REPLACEMENT);
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_PREFIX_V42_7_5)) {
      return replaceGetSchemasQuery(sql, PgJdbcCatalog.PG_JDBC_GET_SCHEMAS_REPLACEMENT_UPPER_CASE);
    }
    if (sql.contains(LiquibaseStatementHelper.TAG_STATEMENT_PART)) {
      return LiquibaseStatementHelper.replaceTagStatement(sql);
    }
    if (sql.endsWith(LiquibaseStatementHelper.MD5SUM_NOT_LIKE)) {
      return sql.replace(
          LiquibaseStatementHelper.MD5SUM_NOT_LIKE,
          LiquibaseStatementHelper.MD5SUM_NOT_LIKE_REPLACEMENT);
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_2)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_3)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_4)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_5)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_6)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_7)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_8)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_9)) {
      if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLES_PREFIX_9)) {
        return replaceGetTablesQuery(sql, PgJdbcCatalog.PG_JDBC_GET_TABLES_REPLACEMENT_UPPER_CASE);
      } else {
        return replaceGetTablesQuery(sql, PgJdbcCatalog.PG_JDBC_GET_TABLES_REPLACEMENT);
      }
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_V42_7_5)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_2)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_3)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_4)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_1_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_2_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_3_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMNS_PREFIX_4_1)) {
      return replaceGetColumnsQuery(sql);
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_V42_7_5)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_2)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_3)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_INDEXES_PREFIX_1_1)) {
      return replaceGetIndexInfoQuery(sql);
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PRIMARY_KEY_PREFIX_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PRIMARY_KEY_PREFIX_2)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PRIMARY_KEY_PREFIX_V42_7_5)) {
      return replaceGetPrimaryKeyQuery(sql);
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_2)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_PREFIX_3)) {
      return PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_1_1)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_COLUMN_PRIVILEGES_PREFIX_V42_7_5)) {
      return PgJdbcCatalog.PG_JDBC_GET_TABLE_PRIVILEGES_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_BEST_ROW_IDENTIFIER_PREFIX)) {
      return PgJdbcCatalog.PG_JDBC_GET_BEST_ROW_IDENTIFIER_REPLACEMENT;
    }

    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_WITH_FUNC_TYPE_PREFIX)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_WITHOUT_FUNC_TYPE_PREFIX)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_UPPER_CASE_PREFIX)) {
      return PgJdbcCatalog.PG_JDBC_GET_FUNCTIONS_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTION_COLUMNS_PREFIX)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_FUNCTION_COLUMNS_PREFIX_V42_7_5)) {
      return PgJdbcCatalog.PG_JDBC_GET_FUNCTION_COLUMNS_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_PREFIX)) {
      return PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_PREFIX_V42_7_5)) {
      return PgJdbcCatalog.PG_JDBC_GET_PROCEDURES_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_UDTS_PREFIX)
        || sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_UDTS_PREFIX_V42_7_5)) {
      return PgJdbcCatalog.PG_JDBC_GET_UDTS_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_MAX_NAME_LENGTH_PREFIX)) {
      return PgJdbcCatalog.PG_JDBC_GET_MAX_NAME_LENGTH_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_SQL_KEYWORDS_PREFIX)) {
      return PgJdbcCatalog.PG_JDBC_GET_SQL_KEYWORDS_REPLACEMENT;
    }
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_GET_SEQUENCES)) {
      return PgJdbcCatalog.PG_JDBC_GET_SEQUENCES_REPLACEMENT;
    }

    // The query that is used to fetch the primary keys of a table was re-written when the PG driver
    // went from 42.2.x to 42.3.x. We translate the 42.3.x query back to the 42.2.x version here,
    // so we can use the same query replacement for both versions.
    if (sql.startsWith(PgJdbcCatalog.PG_JDBC_PK_QUERY_PREFIX_42_3)) {
      sql = replacePG42_3_PkQuery_With_42_2_Query(sql);
    }

    // Replace fixed query prefixes and known unsupported tables.
    return sql
        // Replace fixed query prefixes.
        .replace(PgJdbcCatalog.PG_JDBC_PK_QUERY_PREFIX, PgJdbcCatalog.PG_JDBC_PK_QUERY_REPLACEMENT)
        .replace(
            PgJdbcCatalog.PG_JDBC_BEST_ROW_IDENTIFIER_PREFIX,
            PgJdbcCatalog.PG_JDBC_PK_QUERY_REPLACEMENT)
        .replaceAll(
            PgJdbcCatalog.PG_JDBC_GENERATE_SCHEMAS_ARRAY,
            PgJdbcCatalog.PG_JDBC_GENERATE_SCHEMAS_ARRAY_REPLACEMENT)
        .replaceAll("typinput='array_in'::regproc", "substring(typname, 1, 1)='_'")
        .replaceAll("typinput='pg_catalog\\.array_in'::regproc", "substring(typname, 1, 1)='_'")

        // Replace unsupported pg_catalog tables with fixed (empty) sub-selects.
        .replace(
            " JOIN pg_catalog.pg_description",
            String.format(" JOIN (%s)", PgJdbcCatalog.PG_DESCRIPTION))
        .replace(" pg_catalog.pg_am", String.format(" (%s)", PgJdbcCatalog.PG_AM))
        .replaceAll(
            "\\s+FROM\\s+pg_catalog\\.pg_settings",
            String.format(" FROM (%s) pg_settings", PgJdbcCatalog.PG_SETTINGS))

        // Add joins for tables that miss information to get the required information.
        .replace(
            " JOIN pg_catalog.pg_attribute a",
            String.format(
                " JOIN pg_catalog.pg_attribute a INNER JOIN (%s) a_spanner ON a.attrelid=a_spanner.attrelid AND a.attname=a_spanner.attname",
                PgJdbcCatalog.PG_ATTR_TYPE))

        // Replace select list expressions for those that might miss information.
        .replace(",a.atttypid,", ",coalesce(a.atttypid, a_spanner.spanner_atttypid) as atttypid,")

        // Replace expressions known to be in JDBC metadata queries that are not supported.
        // Replace !~ with NOT <expr> ~
        .replace("AND n.nspname !~ '^pg_'", "AND NOT n.nspname ~ '^pg_'")

        // Replace where and join conditions known to be in JDBC metadata queries that need
        // replacement.
        .replace("AND ci.relam=am.oid", "AND coalesce(ci.relam, 1)=am.oid")
        .replace(
            " ON (a.atttypid = t.oid)",
            " ON (coalesce(a.atttypid, a_spanner.spanner_atttypid) = t.oid)")
        .replace(
            " (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))",
            " (t.typrelid::bigint = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))")

        // Replace function calls for DDL definitions with null literals.
        .replaceAll("pg_catalog\\.pg_get_expr\\(.+?\\)", "null")
        .replaceAll("pg_catalog\\.pg_get_indexdef\\(.+?\\)", "null")

        // Replace unsupported casts.
        .replaceAll("'pg_class'::regclass", "0");
  }