Pros:
- it is convenient to type and read numbers this way;
- Ada, Perl, C++, Go and Rust already support that;
- can support thousands as well as lakhs and crores;

Cons:
- standard SQL does not have this support;
- PostgreSQL treat `SELECT 1_000_000` as number one with `_000_000` alias: http://sqlfiddle.com/#!17/0a28f/400
- C++ has `1'000'000` instead of `1_000_000`;

What do you think?

if (type != "Identifier")
        {
            expected.add(pos, "substitution type (identifier)");
            return false;
        }
        if (pos->type != TokenType::ClosingCurlyBrace)
        {
            expected.add(pos, "closing curly brace");
            return false;
        }
        ++pos;
        node = std::make_shared<ASTIdentifier>("", std::make_shared<ASTQueryParameter>(name, type));
        return true;
    }
    return false;
}
bool ParserCompoundIdentifier::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
    ASTPtr id_list;
    if (!ParserList(std::make_unique<ParserIdentifier>(allow_query_parameter), std::make_unique<ParserToken>(TokenType::Dot), false)
             .parse(pos, id_list, expected))
        return false;
    std::vector<String> parts;
    std::vector<ASTPtr> params;
    const auto & list = id_list->as<ASTExpressionList &>();
    for (const auto & child : list.children)
    {
        parts.emplace_back(getIdentifierName(child));
        if (parts.back().empty())
            params.push_back(child->as<ASTIdentifier>()->getParam());