SQLRETURN RsMetadataServerAPIHelper::callShowTables()

in src/odbc/rsodbc/rsMetadataServerAPIHelper.cpp [425:559]


SQLRETURN RsMetadataServerAPIHelper::callShowTables(
    SQLHSTMT phstmt, const std::string &catalog, const std::string &schema,
    const std::string &table, std::vector<SHOWTABLESResult> &intermediateRS) {
    RS_STMT_INFO *pStmt = (RS_STMT_INFO *)phstmt;
    SQLRETURN rc = SQL_SUCCESS;
    std::string sql;
    std::string quotedCatalog;
    std::string quotedSchema;

    // Input parameter check
    if (catalog.empty()) {
        addError(&pStmt->pErrorList, "HY000",
                 "callShowTables: catalog name should not be null or empty", 0, NULL);
        return SQL_ERROR;
    }

    if (schema.empty()) {
        addError(&pStmt->pErrorList, "HY000",
                 "callShowTables: schema name should not be null or empty", 0, NULL);
        return SQL_ERROR;
    }

    // Apply proper quoting and escaping for identifier
    rc = callQuoteFunc(phstmt, catalog, quotedCatalog, RsMetadataAPIHelper::quotedIdentQuery);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
        addError(&pStmt->pErrorList, "HY000",
                 "callShowColumns: Fail to call QUOTE_IDENT on catalog name", 0,
                 NULL);
        return rc;
    }
    rc = callQuoteFunc(phstmt, schema, quotedSchema, RsMetadataAPIHelper::quotedIdentQuery);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
        addError(&pStmt->pErrorList, "HY000",
                 "callShowColumns: Fail to call QUOTE_IDENT on schema name", 0,
                 NULL);
        return rc;
    }
    

    // Build query for SHOW TABLES
    if (table.empty()) {
        sql = "SHOW TABLES FROM SCHEMA " + quotedCatalog + "." + quotedSchema + ";";
    } else {
        // Apply proper quoting and escaping for literal
        std::string quotedTable;
        rc = callQuoteFunc(phstmt, table, quotedTable, RsMetadataAPIHelper::quotedLiteralQuery);
        if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
            addError(&pStmt->pErrorList, "HY000",
                    "callShowTables: Fail to call QUOTE_LITERAL on table name", 0,
                    NULL);
            return rc;
        }
        sql = "SHOW TABLES FROM SCHEMA " + quotedCatalog + "." + quotedSchema + " LIKE " + quotedTable + ";";
    }

    // Execute Server API call
    RS_LOG_DEBUG("callShowTables", "Execute SHOW query: %s", sql.c_str());
    setCatalogQueryBuf(pStmt, (char *)sql.c_str());
    // TODO: Support for prepare not ready yet
    rc = RsExecute::RS_SQLExecDirect(phstmt, (SQLCHAR *)sql.c_str(), SQL_NTS,
                                     TRUE, FALSE, FALSE, TRUE);
    resetCatalogQueryFlag(pStmt);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
        addError(&pStmt->pErrorList, "HY000",
                 "callShowTables: Fail to execute SHOW TABLES ... ", 0, NULL);
        return rc;
    }

    // Clean up the column binding
    rc = RS_STMT_INFO::RS_SQLFreeStmt(phstmt, SQL_UNBIND, FALSE);
    if (rc != SQL_SUCCESS) {
        addError(&pStmt->pErrorList, "HY000",
                 "callShowTables: Fail to clean up the column binding", 0,
                 NULL);
        return rc;
    }

    // Bind columns for SHOW TABLES result set
    SHOWTABLESResult cur;
    rc += RS_STMT_INFO::RS_SQLBindCol(
        pStmt, getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_database_name),
        SQL_C_CHAR, cur.database_name, sizeof(cur.database_name),
        &cur.database_name_Len);
    rc += RS_STMT_INFO::RS_SQLBindCol(
        pStmt, getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_schema_name),
        SQL_C_CHAR, cur.schema_name, sizeof(cur.schema_name),
        &cur.schema_name_Len);
    rc += RS_STMT_INFO::RS_SQLBindCol(
        pStmt, getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_table_name),
        SQL_C_CHAR, cur.table_name, sizeof(cur.table_name),
        &cur.table_name_Len);
    rc += RS_STMT_INFO::RS_SQLBindCol(
        pStmt, getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_table_type),
        SQL_C_CHAR, cur.table_type, sizeof(cur.table_type),
        &cur.table_type_Len);
    rc += RS_STMT_INFO::RS_SQLBindCol(
        pStmt, getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_remarks),
        SQL_C_CHAR, cur.remarks, sizeof(cur.remarks), &cur.remarks_Len);
    if (rc != SQL_SUCCESS) {
        addError(&pStmt->pErrorList, "HY000",
                 "callShowTables: Fail to bind column for SHOW TABLES "
                 "result ... ",
                 0, NULL);
        return SQL_ERROR;
    }

    // Retrieve result from SHOW TABLES
    while (SQL_SUCCEEDED(
        rc = RS_STMT_INFO::RS_SQLFetchScroll(phstmt, SQL_FETCH_NEXT, 0))) {
        intermediateRS.push_back(cur);
    }

    // Unbind columns for SHOW TABLES result set
    releaseDescriptorRecByNum(
        pStmt->pStmtAttr->pARD,
        getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_database_name));
    releaseDescriptorRecByNum(
        pStmt->pStmtAttr->pARD,
        getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_schema_name));
    releaseDescriptorRecByNum(
        pStmt->pStmtAttr->pARD,
        getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_table_name));
    releaseDescriptorRecByNum(
        pStmt->pStmtAttr->pARD,
        getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_table_type));
    releaseDescriptorRecByNum(
        pStmt->pStmtAttr->pARD,
        getIndex(pStmt, RsMetadataAPIHelper::kSHOW_TABLES_remarks));

    
    // While loop will end if there's no more result to fetch. Therefore, rc
    // will be changed to SQL_ERROR 
    // Simply return SQL_SUCCESS since while loop was finished with no issue
    return SQL_SUCCESS;
}