1. C++ / Говнокод #12077

    +16

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    QString QSqlResultPrivate::positionalToNamedBinding()
    {
        int n = sql.size();
    
        QString result;
        result.reserve(n * 5 / 4);
        bool inQuote = false;
        int count = 0;
    
        for (int i = 0; i < n; ++i) {
            QChar ch = sql.at(i);
            if (ch == QLatin1Char('?') && !inQuote) {
                result += qFieldSerial(count++);
            } else {
                if (ch == QLatin1Char('\''))
                    inQuote = !inQuote;
                result += ch;
            }
        }
        result.squeeze();
        return result;
    }
    
    // Пример запроса:
    // select * from some where d_t = "2012-11-08 12:00:00"

    Словили сегодня вот такой глюк в кутишечке.

    База данных отлично понимает строки и даты в двойных кавычках, все это даже работало какое-то время. Но когда попытались исполнить запрос с таймштампом в двойных кавычках (как в строке 25), начала возникать ошибка в духе "непонятные символы в дате". В одинарных же кавычках все работало. После копания в исходниках и гуглёжки выяснилась и причина - QtSql в упор не видит двойных кавычек, и пытается проставить в них именованные параметры (в нашем случае :00, :00)...

    Если кому нужен быстрофикс - берем тут: https://bugreports.qt-project.org/browse/QTBUG-27159

    Запостил: bormand, 08 Ноября 2012

    Комментарии (11) RSS

    • Блин, не ту функцию выложил:
      QString QSqlResultPrivate::namedToPositionalBinding()
      {
          int n = sql.size();
      
          QString result;
          result.reserve(n);
          bool inQuote = false;
          int count = 0;
          int i = 0;
      
          while (i < n) {
              QChar ch = sql.at(i);
              if (ch == QLatin1Char(':') && !inQuote
                      && (i == 0 || sql.at(i - 1) != QLatin1Char(':'))
                      && (i + 1 < n && qIsAlnum(sql.at(i + 1)))) {
                  int pos = i + 2;
                  while (pos < n && qIsAlnum(sql.at(pos)))
                      ++pos;
                  indexes[sql.mid(i, pos - i)] = count++;
                  result += QLatin1Char('?');
                  i = pos;
              } else {
                  if (ch == QLatin1Char('\''))
                      inQuote = !inQuote;
                  result += ch;
                  ++i;
              }
          }
          result.squeeze();
          return result;
      }
      Ответить
    • какой то хуевый патч, если чо
      select * from some where foo = "Hello d'Artagnan!" and bar = 'trololo'
      Ответить
      • > какой то хуевый патч, если чо
        Так там же:
        if (!inDoubleQuote && ch == QLatin1Char('\''))
            inQuote = !inQuote;
        if (!inQuote && ch == QLatin1Char('\"'))
            inDoubleQuote = !inDoubleQuote;

        Т.е. кавычки внутри других кавычек он нормально распарсит. А вот заэкранированные слешами... но это уже другая история.
        Ответить
        • да
          форматирование в одну строку вскружило мне голову

          а разве в sql они слешами экранируются?
          давно не работал с ним, но помнится, что повторением - типа "" или ''
          Ответить
          • А там чуть ниже можно скачать diff.
            Ответить
          • Да, экранируется повторением апострофа (')
            Ответить
            • Это "лучше'', чем слэшом.
              Ответить
              • Ага, если шрифт не моноширный это смотрится забавно:
                'это два '' апострофа'
                'а это двойная " кавычка'
                Ответить
          • Ну в стандарте не смотрел, не особо нужно было, т.к. есть bindParam() но MySQL точно понимает и "" и \".
            Ответить
    • Потом парень заканчивал, снимал презик, бросал его на пол, а эта самка ожидала следующего героя. Иногда за вечер через Наткину вагину «проходило» до двух десятков парней!
      Ответить
    • Ночью он опять видел тот странный сон: погружённый в беспросветный мрак лес и преследующие его из теней сверкающие глаза. Страх уже скрутил его цепкими лапами, Вит хотел закричать, но с губ срывался лишь еле слышный шёпот. Неожиданно как будто пара сильных рук вырвала его из гибельного оцепенения и потащила за собой, в тепло и безопасность.
      Ответить

    Добавить комментарий