MergeTreeSequentialBlockInputStream::MergeTreeSequentialBlockInputStream(
    const MergeTreeData & storage_,
    const MergeTreeData::DataPartPtr & data_part_,
    Names columns_to_read_,
    bool read_with_direct_io_,
    bool take_column_types_from_storage,
    bool quiet)
    : storage(storage_)
    , data_part(data_part_)
    , part_columns_lock(data_part->columns_lock)
    , columns_to_read(columns_to_read_)
    , read_with_direct_io(read_with_direct_io_)
    , mark_cache(storage.global_context.getMarkCache())
{
    if (!quiet)
    {
        std::stringstream message;
        message << "Reading " << data_part->marks_count << " marks from part " << data_part->name
            << ", total " << data_part->rows_count
            << " rows starting from the beginning of the part, columns: ";
        for (size_t i = 0, size = columns_to_read.size(); i < size; ++i)
            message << (i == 0 ? "" : ", ") << columns_to_read[i];

        LOG_TRACE(log, message.rdbuf());
    }

    addTotalRowsApprox(data_part->rows_count);

    header = storage.getSampleBlockForColumns(columns_to_read);
    fixHeader(header);

    /// Add columns because we don't want to read empty blocks
    injectRequiredColumns(storage, data_part, columns_to_read);
    NamesAndTypesList columns_for_reader;
    if (take_column_types_from_storage)
    {
        const NamesAndTypesList & physical_columns = storage.getColumns().getAllPhysical();
        columns_for_reader = physical_columns.addTypes(columns_to_read);
    }
    else
    {
        /// take columns from data_part
        columns_for_reader = data_part->columns.addTypes(columns_to_read);
    }

    reader = std::make_unique<MergeTreeReader>(
        data_part->getFullPath(), data_part, columns_for_reader, /* uncompressed_cache = */ nullptr,
        mark_cache.get(), /* save_marks_in_cache = */ false, storage,
        MarkRanges{MarkRange(0, data_part->marks_count)},
        /* bytes to use AIO (this is hack) */
        read_with_direct_io ? 1UL : std::numeric_limits<size_t>::max(),
        DBMS_DEFAULT_BUFFER_SIZE);
}
Exemplo n.º 2
0
static void RangeSection (void)
/* Parse a range section */
{
    static const IdentTok RangeDefs[] = {
        {   "COMMENT",          INFOTOK_COMMENT },
        {   "END",              INFOTOK_END     },
        {   "NAME",             INFOTOK_NAME    },
        {   "START",            INFOTOK_START   },
        {   "TYPE",             INFOTOK_TYPE    },
    };

    static const IdentTok TypeDefs[] = {
        {   "ADDRTABLE",        INFOTOK_ADDRTAB  },
        {   "BYTETABLE",        INFOTOK_BYTETAB  },
        {   "CODE",             INFOTOK_CODE     },
        {   "DBYTETABLE",       INFOTOK_DBYTETAB },
        {   "DWORDTABLE",       INFOTOK_DWORDTAB },
        {   "RTSTABLE",         INFOTOK_RTSTAB   },
        {   "SKIP",             INFOTOK_SKIP     },
        {   "TEXTTABLE",        INFOTOK_TEXTTAB  },
        {   "WORDTABLE",        INFOTOK_WORDTAB  },
    };


    /* Which values did we get? */
    enum {
        tNone   = 0x00,
        tStart  = 0x01,
        tEnd    = 0x02,
        tType   = 0x04,
        tName   = 0x08,
        tComment= 0x10,
        tNeeded = (tStart | tEnd | tType)
    };
    unsigned Attributes = tNone;

    /* Locals - initialize to avoid gcc warnings */
    unsigned Start      = 0;
    unsigned End        = 0;
    unsigned char Type  = 0;
    char* Name          = 0;
    char* Comment       = 0;
    unsigned MemberSize = 0;


    /* Skip the token */
    InfoNextTok ();

    /* Expect the opening curly brace */
    InfoConsumeLCurly ();

    /* Look for section tokens */
    while (InfoTok != INFOTOK_RCURLY) {

        /* Convert to special token */
        InfoSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range attribute");

        /* Look at the token */
        switch (InfoTok) {

            case INFOTOK_COMMENT:
                AddAttr ("COMMENT", &Attributes, tComment);
                InfoNextTok ();
                InfoAssureStr ();
                if (InfoSVal[0] == '\0') {
                    InfoError ("Comment may not be empty");
                }
                Comment = xstrdup (InfoSVal);
                Attributes |= tComment;
                InfoNextTok ();
                break;

            case INFOTOK_END:
                AddAttr ("END", &Attributes, tEnd);
                InfoNextTok ();
                InfoAssureInt ();
                InfoRangeCheck (0x0000, 0xFFFF);
                End = InfoIVal;
                InfoNextTok ();
                break;

            case INFOTOK_NAME:
                AddAttr ("NAME", &Attributes, tName);
                InfoNextTok ();
                InfoAssureStr ();
                if (InfoSVal[0] == '\0') {
                    InfoError ("Name may not be empty");
                }
                Name = xstrdup (InfoSVal);
                Attributes |= tName;
                InfoNextTok ();
                break;

            case INFOTOK_START:
                AddAttr ("START", &Attributes, tStart);
                InfoNextTok ();
                InfoAssureInt ();
                InfoRangeCheck (0x0000, 0xFFFF);
                Start = InfoIVal;
                InfoNextTok ();
                break;

            case INFOTOK_TYPE:
                AddAttr ("TYPE", &Attributes, tType);
                InfoNextTok ();
                InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "TYPE");
                switch (InfoTok) {
                    case INFOTOK_ADDRTAB:  Type = atAddrTab;  MemberSize = 2; break;
                    case INFOTOK_BYTETAB:  Type = atByteTab;  MemberSize = 1; break;
                    case INFOTOK_CODE:     Type = atCode;     MemberSize = 1; break;
                    case INFOTOK_DBYTETAB: Type = atDByteTab; MemberSize = 2; break;
                    case INFOTOK_DWORDTAB: Type = atDWordTab; MemberSize = 4; break;
                    case INFOTOK_RTSTAB:   Type = atRtsTab;   MemberSize = 2; break;
                    case INFOTOK_SKIP:     Type = atSkip;     MemberSize = 1; break;
                    case INFOTOK_TEXTTAB:  Type = atTextTab;  MemberSize = 1; break;
                    case INFOTOK_WORDTAB:  Type = atWordTab;  MemberSize = 2; break;
                }
                InfoNextTok ();
                break;

            default:
                Internal ("Unexpected token: %u", InfoTok);
        }

        /* Directive is followed by a semicolon */
        InfoConsumeSemi ();

    }

    /* Did we get all required values? */
    if ((Attributes & tNeeded) != tNeeded) {
        InfoError ("Required values missing from this section");
    }

    /* Start must be less than end */
    if (Start > End) {
        InfoError ("Start value must not be greater than end value");
    }

    /* Check the granularity */
    if (((End - Start + 1) % MemberSize) != 0) {
        InfoError ("Type of range needs a granularity of %u", MemberSize);
    }

    /* Set the range */
    MarkRange (Start, End, Type);

    /* Do we have a label? */
    if (Attributes & tName) {

        /* Define a label for the table */
        AddExtLabel (Start, Name);

        /* Set the comment if we have one */
        if (Comment) {
            SetComment (Start, Comment);
        }

        /* Delete name and comment */
        xfree (Name);
        xfree (Comment);
    }

    /* Consume the closing brace */
    InfoConsumeRCurly ();
}