Пример #1
0
bool SqlParser::parseSimpleTableNameAndAlias(int start, int end,
        StringVector &tableNames,
        StringVector &aliases) const {
    if (end - start == 1) {
        if (getTokenId(start) == TK_LITERAL) {
            tableNames.push_back(getTokenStr(start));
            aliases.push_back("");
            return true;
        }
    } else if (end - start == 2) {
        if (getTokenId(start) == TK_LITERAL &&
                getTokenId(start + 1) == TK_LITERAL) {
            tableNames.push_back(getTokenStr(start));
            aliases.push_back(getTokenStr(start + 1));
            return true;
        }
    } else if (end - start == 3 && getTokenId(start + 1) == TK_SQL_AS) {
        if (getTokenId(start) == TK_LITERAL &&
                getTokenId(start + 2) == TK_LITERAL) {
            tableNames.push_back(getTokenStr(start));
            aliases.push_back(getTokenStr(start + 2));
            return true;
        }
    }

    return false;
}
Пример #2
0
bool SqlParser::setDefaultLimit() {
    static const char *defaultLimit = NULL;
    if (defaultLimit == NULL) {
        defaultLimit = get_config_string("DEFAULT_SELECT_LIMIT");
        if (defaultLimit == NULL)
            defaultLimit = "500";
    }

    int limitPos;
    if (!findToken(1, getTokensLen(), TK_SQL_LIMIT, &limitPos)) {
        g_string_append(inputSql, " LIMIT ");
        g_string_append(inputSql, defaultLimit);
        network_mysqld_proto_set_header_len((unsigned char *) (inputSql->str), inputSql->len - NET_HEADER_SIZE);

        return true;
    }

    if (limitPos + 3 > getTokensLen() - 1) // no offset
        return true;

    if (limitPos + 3 < getTokensLen() - 1) {
        printTokens("only queries with LIMIT at the last field is supported now!");
        return false;
    }

    int offset, rowCount;
    if (getTokenId(limitPos + 2) == TK_COMMA) {
        offset = atoi(getTokenStr(limitPos + 1).c_str());
        rowCount = atoi(getTokenStr(limitPos + 3).c_str());
    } else if (getTokenId(limitPos + 2) == TK_SQL_OFFSET) {
        offset = atoi(getTokenStr(limitPos + 3).c_str());
        rowCount = atoi(getTokenStr(limitPos + 1).c_str());
    } else {
        printTokens("Unrecognized LIMIT OFFSET format:");
        return false;
    }

    // TODO: the tokenizer needs to have the field offset info
    // for now, we search LIMIT from the end
    char *p = inputSql->str + inputSql->len - 1;
    while (toupper(*p) != 'L') p--;

    // remove the old LIMIT OFFSET info
    //
    g_string_truncate(inputSql, p - inputSql->str);

    // add new LIMIT OFFSET info
    char buff[128];
    snprintf(buff, sizeof (buff), "LIMIT %d", offset + rowCount);
    g_string_append(inputSql, buff);
    network_mysqld_proto_set_header_len((unsigned char *) (inputSql->str), inputSql->len - NET_HEADER_SIZE);

    return true;
}
Пример #3
0
bool outputProductsTree(const char fileName[])
{
    int curIndent=0,curPro;
    Token tk;
    initReadOneToken();
    string tmpStr="";
    std::vector<Symbol> symvct;
    std::vector<int> symIndentVct;
    symvct.push_back(Symbol::Program);
    symIndentVct.push_back(curIndent);
    FILE * fn=fopen(fileName,"w");
    if(!fn) return false;

    for(int pseq=0;pseq<productsSequence.size();)
    {
        if(isTerminalSymbol(symvct.back()))
        {
            if(!ReadOneToken(tk))
                printf("something is wrong when get new token.");
            tmpStr=_getBlankStr_(symIndentVct.back())+getTokenStr(tk.type)+" "+tk.name;
            fprintf(fn,"%s\n",tmpStr.c_str());
            symvct.pop_back();
            symIndentVct.pop_back();
        }
        else
        {
            curIndent=symIndentVct.back();
            tmpStr=_getBlankStr_(curIndent)+getTokenStr(symvct.back());
            fprintf(fn,"%s\n",tmpStr.c_str());
            curIndent+=2;

            curPro=productsSequence[pseq++];
            //printf("%d ",curPro);
            symIndentVct.pop_back();
            symvct.pop_back();
            for(int i=(products[curPro].size())-1;i>0;i--)
                if(products[curPro][i]!=Symbol::LAMBDA)
                {
                    symvct.push_back(products[curPro][i]);
                    symIndentVct.push_back(curIndent);
                }
                else
                {
                    tmpStr=_getBlankStr_(curIndent)+"LAMBDA";
                    fprintf(fn,"%s\n",tmpStr.c_str());
                }

        }

    }
    fclose(fn);
    initReadOneToken();
    return true;
}
Пример #4
0
void pushProduct(int num)/**将产生式右部入栈**/
{
    productsSequence.push_back(num);
    for(int i=int(products[num].size())-1; i>0; i--)
        if(products[num][i]!=Symbol::LAMBDA)///lambda 不用入符号栈
            symbolStack.push_back(products[num][i]);
#ifdef LL1OUTPUTPRODUCT    /**输出调试信息**/
    printf(": %-3d ",num);
    for(Symbol tmp:products[num])
        printf("%-8s ",getTokenStr(tmp).c_str());
    puts("");
#endif // LL1OUTPUTPRODUCT
#ifdef LL1OUTSYMBOLSTACK    /**输出调试信息**/
    puts("Rest Symbol in Stack is:");
    for(Symbol tmp:symbolStack)
        printf("%-8s ",getTokenStr(tmp).c_str());
    puts("");
#endif // LL1OUTSYMBOLSTACK
}
Пример #5
0
void SqlParser::printTokens(const char *str) const {
    std::string msg(str ? str : "");
    if (inputSql) {
        msg.append("\"");
        msg.append(inputSql->str + NET_HEADER_SIZE + 1, inputSql->len - NET_HEADER_SIZE - 1);
        msg.append("\".");
    }

    log_warning(msg.c_str());

    for (size_t i = 0; i < tokens->len; i++) {
        log_debug("SQL Tokens: %2d %20s: \"%s\"\n", i,
                sql_token_get_name(getTokenId(i)),
                getTokenStr(i).c_str());
    }

}
Пример #6
0
db_lookup_retval_t SqlParser::parseSql(std::set<std::string> &dbs, int *txLevel, bool parseMaster) {
    dbs.clear();

    StringVector tables, aliases;

    if (getTokensLen() <= 0) {
        log_warning("empty sql for dababase lookup!\n");
        return RET_ERROR_UNPARSABLE;
    }

    switch (getTokenId(0)) {
        case TK_SQL_SELECT:
        {
            int usemaster = 0;
            if (parseMaster) usemaster = 1;
            // special handling for our get unique id function call.
            if (getTokensLen() > 1 && getTokenStr(1) == "get_next_id")
                return RET_USE_DEFAULT_DATABASE;

            int fromStart, fromEnd;

            if (!getSqlFrom(0, &fromStart, &fromEnd)) {
                if ((getTokensLen() > 3 && getTokenId(1) == TK_LITERAL &&
                        getTokenId(2) == TK_OBRACE) ||
                        (getTokensLen() == 2 && getTokenId(1) == TK_LITERAL)) {

                    // for special stored procedures
                    return RET_USE_ALL_PARTITIONS;
                }

                printTokens("no FROM found, using default db: ");
                return RET_USE_DEFAULT_DATABASE;
            }

            if (!parseTableNameAndAlias(fromStart, fromEnd, tables, aliases)) {
                printTokens("could not parse table alias, using default db: ");
                return RET_USE_DEFAULT_DATABASE;
            }

            // for non-partitioned tables, we can use any db
            // since each db should have a view of it
            bool partitioned = false;
            for (size_t i = 0; i < tables.size(); i++) {
                if (dbPart->isPartitionedTable(tables[i])) {
                    partitioned = true;
                    break;
                }
            }
            if (!setDefaultLimit()) {
                printTokens("error in modifying LIMIT: ");
                return RET_ERROR_UNPARSABLE;
            }
            /*
               if (!partitioned)
               return ((*txLevel) > 0 ? RET_USE_DEFAULT_DATABASE : RET_USE_ANY_PARTITION);
             */
            int whereStart, whereEnd;
            if (!getSqlWhere(fromEnd, &whereStart, &whereEnd)) {
                // add LIMIT, change the offset to 0 if needed
                uint64_t aa = 0;
                dbPart->getPartitionNum(tables[0], &aa);

                for (size_t i = 0; i < aa; i++) {
                    std::string db;
                    getDbMapping(tables[0], "", i, db, usemaster, 0);
                    if (!db.empty())
                        dbs.insert(db);
                }
                return RET_USE_ALL_PARTITIONS;
            }

            for (size_t i = 0; i < tables.size(); i++) {
                std::string partitionKey;
                getPartitionKey(tables[i], partitionKey);
                if (partitionKey.empty()) {
                    std::string db;
                    getDbMapping(tables[i], "", 0, db, usemaster, 0);
                    if (!db.empty())
                        dbs.insert(db);
                    continue;
                }


                std::vector<uint64_t> keyValues;
                if (!findPartitionKeyValue(whereStart, whereEnd, tables[i],
                        aliases[i], partitionKey, keyValues)) {
                    printTokens("unrecognized key ranges: ");
                    return RET_ERROR_UNPARSABLE;
                }
                if (keyValues.size() == 0) {
                    uint64_t aa = 0;
                    dbPart->getPartitionNum(tables[0], &aa);

                    for (size_t i = 0; i < aa; i++) {
                        std::string db;
                        getDbMapping(tables[0], "", i, db, usemaster, 0);
                        if (!db.empty())
                            dbs.insert(db);
                    }
                    return RET_USE_ALL_PARTITIONS;
                }

                // find the db partition for all the IDs
                for (size_t k = 0; k < keyValues.size(); k++) {
                    std::string db;
                    getDbMapping(tables[i], partitionKey, keyValues[k], db, usemaster, 0);
                    if (!db.empty())
                        dbs.insert(db);
                }
            }



            if (dbs.empty())
                return RET_USE_ALL_PARTITIONS;

            return RET_DB_LOOKUP_SUCCESS;
        }
        case TK_SQL_UPDATE:
        {
            int setPos;
            if (!findToken(0, getTokensLen(), TK_SQL_SET, &setPos)) {
                printTokens("could not find SET in UPDATE: ");
                return RET_ERROR_UNPARSABLE;
            };

            if (getTokenId(setPos - 1) != TK_LITERAL) {
                printTokens("expecting table name before SET: ");
                return RET_ERROR_UNPARSABLE;
            }

            std::string table = getTokenStr(setPos - 1);

            // for nonpartitioned tables, update the default master db
            if (!(dbPart->isPartitionedTable(table))) {
                std::string db;
                getDbMapping(table, "", 0, db, 1, 0);
                if (!db.empty())
                    dbs.insert(db);
                return RET_USE_ALL_PARTITIONS;
            }

            int whereStart, whereEnd;
            if (!getSqlWhere(setPos + 1, &whereStart, &whereEnd)) {
                printTokens("no WHERE found: ");
                return RET_ERROR_UNPARSABLE;
            }

            std::string partitionKey;
            getPartitionKey(table, partitionKey);

            g_assert(!partitionKey.empty());

            std::vector<uint64_t> keyValues;
            if (!findPartitionKeyValue(whereStart, whereEnd, table, "",
                    partitionKey, keyValues)) {
                printTokens("unrecognized ranges: ");
                return RET_ERROR_UNPARSABLE;
            }

            // find the db partition for all the IDs
            for (size_t k = 0; k < keyValues.size(); k++) {
                std::string db;
                getDbMapping(table, partitionKey, keyValues[k], db, 1, 0);
                if (!db.empty())
                    dbs.insert(db);
            }

            if (dbs.empty())
                return RET_USE_ALL_PARTITIONS;

            return RET_DB_LOOKUP_SUCCESS;
        }
        case TK_SQL_INSERT:
        { // support format: INSERT  ... <table> (...) VALUES (....)

            int pos;
            uint64_t insertid = 0;
            if (!findToken(1, getTokensLen(), TK_LITERAL, &pos)) {
                printTokens("could not find table name: ");
                return RET_ERROR_UNPARSABLE;
            }

            std::string table = getTokenStr(pos);

            std::string partitionKey;
            getPartitionKey(table, partitionKey);

            if (getTokenId(++pos) != TK_OBRACE) {
                printTokens("unrecognized INSERT: ");
                return RET_ERROR_UNPARSABLE;
            }

            pos++;

            std::string autoIncrementColumn;
            dbPart->getAutoIncrementColumn(table, autoIncrementColumn);

            int keyPos = -1;
            int autoColPos = -1;
            for (int i = pos; i < getTokensLen(); i++) {
                if ((getTokenId(i) == TK_CBRACE) ||
                        (autoColPos >= 0 && keyPos >= 0))
                    break;
                if (getTokenId(i) == TK_LITERAL &&
                        tokComp(i, partitionKey) == 0) {
                    keyPos = i - pos;
                    continue;
                }
                if (getTokenId(i) == TK_LITERAL &&
                        tokComp(i, autoIncrementColumn) == 0) {
                    autoColPos = i - pos;
                }
            }

            if ((!partitionKey.empty()) && keyPos == -1 && partitionKey != autoIncrementColumn) {
                log_warning("could not find the partition key %s:", partitionKey.c_str());
                printTokens();
                return RET_ERROR_UNPARSABLE;
            }

            if ((!partitionKey.empty()) && keyPos == -1) {
                // special handling for the case in which partition key type is auto increment.
                // need to get the id first and then modify the INSERT
                uint64_t id;
                if (!dbPart->getNextUniqueId(table, &id)) {
                    log_warning("could not get next unique id for %s", partitionKey.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
                insertid = id;
                std::string db;
                getDbMapping(table, partitionKey, id, db, 1, id);
                if (!db.empty())
                    dbs.insert(db);
                else {
                    printTokens("could not find db for id %d: ");
                    return RET_DB_LOOKUP_ERROR;
                }

                if (modifySqlForInsert(partitionKey, id)) {
                    if (partitionKey == autoIncrementColumn || autoIncrementColumn.empty())
                        return RET_DB_LOOKUP_SUCCESS;
                } else {
                    log_warning("could not insert id for %s ", partitionKey.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
            }

            if (!autoIncrementColumn.empty() && autoColPos < 0 && (partitionKey != autoIncrementColumn)) {
                // need to get unique ids for auto increment columns
                uint64_t id;
                if (!dbPart->getNextUniqueId(table, &id)) {
                    log_warning("could not get next unique id for %s", autoIncrementColumn.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
                insertid = id;
                if (modifySqlForInsert(autoIncrementColumn, id)) {
                    // for nonparitioned table INSERT, use the default master db
                    if (partitionKey.empty())
                        return RET_USE_DEFAULT_DATABASE;

                    if (keyPos == -1)
                        return RET_DB_LOOKUP_SUCCESS;
                } else {
                    log_warning("could not insert id for %s ", autoIncrementColumn.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
            }

            // for nonparitioned table INSERT, use the default master db
            if (partitionKey.empty()) {
                std::string db;
                getDbMapping(table, "", 0, db, 1, insertid);
                if (!db.empty())
                    dbs.insert(db);
                return RET_USE_ALL_PARTITIONS;
            }

            pos += keyPos;

            int valPos;

            if (!findToken(pos, getTokensLen(), TK_SQL_VALUES, &valPos)) {
                printTokens("VALUES is not found: ");
                return RET_ERROR_UNPARSABLE;
            }

            if (getTokenId(valPos + 1) != TK_OBRACE) {
                printTokens("expecting '(' after VALUES: ");
                return RET_ERROR_UNPARSABLE;
            }

            pos = valPos + 2 + keyPos;
            if (pos < getTokensLen()) {//dqm
                //if (pos < getTokensLen() && getTokenId(pos) == TK_INTEGER) {
                uint64_t id = tokenToUint64(pos);
                std::string db;
                getDbMapping(table, partitionKey, id, db, 1, insertid);
                if (!db.empty())
                    dbs.insert(db);

                if (dbs.empty()) {
                    printTokens("could not find db mapping: ");
                    return RET_ERROR_UNPARSABLE;
                }

                return RET_DB_LOOKUP_SUCCESS;
            } else {
                log_warning("could not recognize value for %s:", partitionKey.c_str());
                printTokens();
                return RET_ERROR_UNPARSABLE;
            }

            break;
        }
        
        case TK_SQL_REPLACE:
        { // support format: replace  ... <table> (...) VALUES (....)

            int pos;
            uint64_t insertid = 0;
            if (!findToken(1, getTokensLen(), TK_LITERAL, &pos)) {
                printTokens("could not find table name: ");
                return RET_ERROR_UNPARSABLE;
            }

            std::string table = getTokenStr(pos);

            std::string partitionKey;
            getPartitionKey(table, partitionKey);

            if (getTokenId(++pos) != TK_OBRACE) {
                printTokens("unrecognized INSERT: ");
                return RET_ERROR_UNPARSABLE;
            }

            pos++;

            std::string autoIncrementColumn;
            dbPart->getAutoIncrementColumn(table, autoIncrementColumn);

            int keyPos = -1;
            int autoColPos = -1;
            for (int i = pos; i < getTokensLen(); i++) {
                if ((getTokenId(i) == TK_CBRACE) ||
                        (autoColPos >= 0 && keyPos >= 0))
                    break;
                if (getTokenId(i) == TK_LITERAL &&
                        tokComp(i, partitionKey) == 0) {
                    keyPos = i - pos;
                    continue;
                }
                if (getTokenId(i) == TK_LITERAL &&
                        tokComp(i, autoIncrementColumn) == 0) {
                    autoColPos = i - pos;
                }
            }

            if ((!partitionKey.empty()) && keyPos == -1 && partitionKey != autoIncrementColumn) {
                log_warning("could not find the partition key %s:", partitionKey.c_str());
                printTokens();
                return RET_ERROR_UNPARSABLE;
            }

            if ((!partitionKey.empty()) && keyPos == -1) {
                // special handling for the case in which partition key type is auto increment.
                // need to get the id first and then modify the INSERT
                uint64_t id;
                if (!dbPart->getNextUniqueId(table, &id)) {
                    log_warning("could not get next unique id for %s", partitionKey.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
                insertid = id;
                std::string db;
                getDbMapping(table, partitionKey, id, db, 1, id);
                if (!db.empty())
                    dbs.insert(db);
                else {
                    printTokens("could not find db for id %d: ");
                    return RET_DB_LOOKUP_ERROR;
                }

                if (modifySqlForInsert(partitionKey, id)) {
                    if (partitionKey == autoIncrementColumn || autoIncrementColumn.empty())
                        return RET_DB_LOOKUP_SUCCESS;
                } else {
                    log_warning("could not insert id for %s ", partitionKey.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
            }

            if (!autoIncrementColumn.empty() && autoColPos < 0 && (partitionKey != autoIncrementColumn)) {
                // need to get unique ids for auto increment columns
                uint64_t id;
                if (!dbPart->getNextUniqueId(table, &id)) {
                    log_warning("could not get next unique id for %s", autoIncrementColumn.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
                insertid = id;
                if (modifySqlForInsert(autoIncrementColumn, id)) {
                    // for nonparitioned table INSERT, use the default master db
                    if (partitionKey.empty())
                        return RET_USE_DEFAULT_DATABASE;

                    if (keyPos == -1)
                        return RET_DB_LOOKUP_SUCCESS;
                } else {
                    log_warning("could not insert id for %s ", autoIncrementColumn.c_str());
                    printTokens();
                    return RET_DB_LOOKUP_ERROR;
                }
            }

            // for nonparitioned table INSERT, use the default master db
            if (partitionKey.empty()) {
                std::string db;
                getDbMapping(table, "", 0, db, 1, insertid);
                if (!db.empty())
                    dbs.insert(db);
                return RET_USE_ALL_PARTITIONS;
            }

            pos += keyPos;

            int valPos;

            if (!findToken(pos, getTokensLen(), TK_SQL_VALUES, &valPos)) {
                printTokens("VALUES is not found: ");
                return RET_ERROR_UNPARSABLE;
            }

            if (getTokenId(valPos + 1) != TK_OBRACE) {
                printTokens("expecting '(' after VALUES: ");
                return RET_ERROR_UNPARSABLE;
            }

            pos = valPos + 2 + keyPos;
            if (pos < getTokensLen()) {//dqm
                //if (pos < getTokensLen() && getTokenId(pos) == TK_INTEGER) {
                uint64_t id = tokenToUint64(pos);
                std::string db;
                getDbMapping(table, partitionKey, id, db, 1, insertid);
                if (!db.empty())
                    dbs.insert(db);

                if (dbs.empty()) {
                    printTokens("could not find db mapping: ");
                    return RET_ERROR_UNPARSABLE;
                }

                return RET_DB_LOOKUP_SUCCESS;
            } else {
                log_warning("could not recognize value for %s:", partitionKey.c_str());
                printTokens();
                return RET_ERROR_UNPARSABLE;
            }

            break;
        }

        case TK_SQL_ALTER:
        {
            std::string tableName;
            if (getTokensLen() >= 3 && getTokenId(1) == TK_SQL_TABLE) {
                tableName = getTokenStr(2);
            } else if (getTokensLen() >= 4 && getTokenId(1) == TK_SQL_IGNORE &&
                    getTokenId(2) == TK_SQL_TABLE) {
                tableName = getTokenStr(3);
            } else
                break;
            if (dbPart->isPartitionedTable(tableName))
                return RET_USE_ALL_PARTITIONS;
            else
                return RET_USE_DEFAULT_DATABASE;
        }

        case TK_SQL_CALL:
        {
            return RET_USE_ALL_PARTITIONS;
        }

        case TK_SQL_SHOW:
        {
            if (getTokensLen() == 4 && getTokenId(2) == TK_SQL_FROM &&
                    strcasecmp(getTokenStr(1).c_str(), "fields") == 0) {

                if (dbPart->isPartitionedTable(getTokenStr(3))) {
                    return RET_USE_ANY_PARTITION;
                }
                return RET_USE_DEFAULT_DATABASE;
            }

            if (getTokensLen() == 2 &&
                    strcasecmp(getTokenStr(1).c_str(), "tables") == 0) {

                //special handling for show tables;
                //
                std::string sql = "select table_name ";
                sql.append(" from kind_setting order by table_name");
                g_string_truncate(inputSql, NET_HEADER_SIZE + 1);
                g_string_append_len(inputSql, sql.data(), sql.size());

                network_mysqld_proto_set_header_len((unsigned char *) (inputSql->str),
                        inputSql->len - NET_HEADER_SIZE);

                return RET_USE_DEFAULT_DATABASE;
            } else
                return RET_USE_DEFAULT_DATABASE;

            break;
        }

        case TK_SQL_DELETE:
        {
            int fromPos;
            if (!findToken(1, getTokensLen(), TK_SQL_FROM, &fromPos)) {
                printTokens("could not find FROM in DELETE: ");
                return RET_ERROR_UNPARSABLE;
            };

            if (fromPos >= getTokensLen() - 1) {
                printTokens("could not find table name in DELETE: ");
                return RET_ERROR_UNPARSABLE;
            }

            std::string table = getTokenStr(fromPos + 1);
            // for nonpartitioned tables, update the default master db
            if (!(dbPart->isPartitionedTable(table))) {
                std::string db;
                getDbMapping(table, "", 0, db, 1, 0);
                if (!db.empty())
                    dbs.insert(db);
                return RET_USE_ALL_PARTITIONS;
            }

            int whereStart, whereEnd;
            if (!getSqlWhere(fromPos + 1, &whereStart, &whereEnd)) {
                printTokens("no WHERE found: ");
                return RET_ERROR_UNPARSABLE;
            }

            std::string partitionKey;
            getPartitionKey(table, partitionKey);

            g_assert(!partitionKey.empty());

            std::vector<uint64_t> keyValues;
            if (!findPartitionKeyValue(whereStart, whereEnd, table, "",
                    partitionKey, keyValues)) {
                printTokens("unrecognized ranges: ");
                return RET_ERROR_UNPARSABLE;
            }

            // find the db partition for all the IDs
            for (size_t k = 0; k < keyValues.size(); k++) {
                std::string db;
                getDbMapping(table, partitionKey, keyValues[k], db, 1, 0);
                if (!db.empty())
                    dbs.insert(db);
            }

            if (dbs.empty())
                return RET_USE_ALL_PARTITIONS;

            return RET_DB_LOOKUP_SUCCESS;
        }
        case TK_SQL_DESC:
        case TK_SQL_DESCRIBE:
        {
            if (getTokensLen() >= 2) {
                std::string tableName = getTokenStr(1);
                if (dbPart->isPartitionedTable(tableName))
                    return RET_USE_ANY_PARTITION;
                else
                    return RET_USE_DEFAULT_DATABASE;
            }

            return RET_ERROR_UNPARSABLE;
        }
        case TK_SQL_SET:
        {
            if ((getTokensLen() >= 4) &&
                    (getTokenId(1) == TK_SQL_AUTOCOMMIT) &&
                    (getTokenStr(3).compare("0") == 0)) {
                (*txLevel)++;
            }
            return RET_USE_ALL_DATABASES;
        }
        case TK_SQL_START:
        case TK_SQL_BEGIN:
        {
            (*txLevel)++;
            return RET_USE_ALL_DATABASES;
        }
        case TK_SQL_COMMIT:
        case TK_SQL_ROLLBACK:
        {
            (*txLevel)--;
            return RET_USE_ALL_DATABASES;
        }
        default:
        {
            break;
        }
    }

    printTokens("unrecognized query, using default master db: ");

    return RET_USE_DEFAULT_DATABASE;
}
Пример #7
0
bool parserLL1()/***语法分析主函数,返回真假值表示是否出现了语法错误***/
{
    /***init***/
    if(!isInitFuncs)
    {
        initParserLL1Funcs();
        isInitFuncs=true;
    }
    deleteParserLL1Tree();
    expflag=0;
    getExpResult2=false;
    getExpResult=true;
    savePtr=NULL;
    errors.clear();
    CreatLL1Table();
    symbolStack.clear();
    operatorStack.clear();
    numStack.clear();
    syntaxStack.clear();
    productsSequence.clear();
    symbolStack.push_back(Symbol::Program);
    rt=new TreeNode(0,NodeKinds::ProK);///根节点
    for(int i=2; i>=0; i--)
        syntaxStack.push_back(&(rt->son[i]));
    /***init***/
    ReadOneToken(currentToken);
    while(!symbolStack.empty())
    {
        if(isTerminalSymbol(symbolStack.back()))///终极符
        {
            if(currentToken.type==symbolStack.back())
            {
                symbolStack.pop_back();
#ifdef LL1CURTERMINALSYMBOL  /**输出调试信息**/
                printf(">>>>>>  Pop Terminal Symbol %s\n",currentToken.name.c_str());
#endif // LL1CURTERMINALSYMBOL
                ReadOneToken(currentToken);
            }
            else
            {
                sprintf(strError,"syntax error : unexpected tokentype= '%s' name= %s found at line %d,\n\
                        expected Token type is %s.\n",
                        getTokenStr(currentToken.type).c_str(),currentToken.name.c_str(),
                        currentToken.lineNum,getTokenStr(symbolStack.back()).c_str());
                insertError(strError);
#ifdef LL1OUTSYMBOLSTACK   /**输出调试信息**/
                puts("Rest Symbol in Stack is:");
                for(Symbol tmp:symbolStack)
                    printf("%-8s ",getTokenStr(tmp).c_str());
                puts("");
#endif // LL1OUTSYMBOLSTACK
                return false;
            }
        }
        else///非终极符
        {
            int pnum=LL1Table[int(symbolStack.back())][int(currentToken.type)];///取得对应的产生式
            printf("LL1 List %s %s \n",getTokenStr(symbolStack.back()).c_str(),getTokenStr(currentToken.type).c_str());
            Symbol tsym=symbolStack.back();
            symbolStack.pop_back();
            if(!chooseFunc(pnum))///没有对应的产生式
            {
                 printf("ok shit???????????");
                sprintf(strError,"syntax error : unexpected tokentype= '%s' name= %s found at line %d.\n  maybe missed one of these: %s",
                                        getTokenStr(currentToken.type).c_str(),currentToken.name.c_str(),
                                        currentToken.lineNum,getPredictStr(tsym).c_str());
                insertError(strError);
                return false;
            }
        }
    }
    if(currentToken.type!=TokenType::DOT)/***匹配结束符 . ***/
    {
        sprintf(strError,"syntax error : unexpected token found at line %d,Expected Dot\n",currentToken.lineNum);
        insertError(strError);
        return false;
    }
    else if(!ReadOneToken(currentToken))/***有结束符 . 则读入下一个TOKEN EOF***/
    {
        sprintf(strError,"syntax error : Token ends Before Code or File end\n");
        insertError(strError);
        return false;
    }
    if(currentToken.type==TokenType::ENDFILE)
        return true;
    else
    {
        sprintf(strError,"syntax error : unexpected token '%s' found at line %d,Expected EOF\n"
                ,getTokenStr(currentToken.type).c_str(),currentToken.lineNum);
        insertError(strError);
        return false;
    }
    return errors.size()==0;
}
Пример #8
0
char *staticGetTokenStr(pToken t, int useTargetLang) {
    static char buffer[MAX_PRINT_TOKEN_SIZE];
    return getTokenStr(t, useTargetLang, buffer);
}