public ParseInfo()

in src/main/core-api/java/com/mysql/cj/ParseInfo.java [96:289]


    public ParseInfo(String sql, Session session, String encoding, boolean buildRewriteInfo) {

        try {
            if (sql == null) {
                throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("PreparedStatement.61"),
                        session.getExceptionInterceptor());
            }

            this.charEncoding = encoding;
            this.lastUsed = System.currentTimeMillis();

            String quotedIdentifierString = session.getIdentifierQuoteString();

            char quotedIdentifierChar = 0;

            if ((quotedIdentifierString != null) && !quotedIdentifierString.equals(" ") && (quotedIdentifierString.length() > 0)) {
                quotedIdentifierChar = quotedIdentifierString.charAt(0);
            }

            this.statementLength = sql.length();

            ArrayList<int[]> endpointList = new ArrayList<>();
            boolean inQuotes = false;
            char quoteChar = 0;
            boolean inQuotedId = false;
            int lastParmEnd = 0;
            int i;

            boolean noBackslashEscapes = session.getServerSession().isNoBackslashEscapesSet();

            // we're not trying to be real pedantic here, but we'd like to  skip comments at the beginning of statements, as frameworks such as Hibernate
            // use them to aid in debugging

            this.statementStartPos = findStartOfStatement(sql);

            for (i = this.statementStartPos; i < this.statementLength; ++i) {
                char c = sql.charAt(i);

                if ((this.firstStmtChar == 0) && Character.isLetter(c)) {
                    // Determine what kind of statement we're doing (_S_elect, _I_nsert, etc.)
                    this.firstStmtChar = Character.toUpperCase(c);

                    // no need to search for "ON DUPLICATE KEY UPDATE" if not an INSERT statement
                    if (this.firstStmtChar == 'I') {
                        this.locationOfOnDuplicateKeyUpdate = getOnDuplicateKeyLocation(sql,
                                session.getPropertySet().getBooleanProperty(PropertyKey.dontCheckOnDuplicateKeyUpdateInSQL).getValue(),
                                session.getPropertySet().getBooleanProperty(PropertyKey.rewriteBatchedStatements).getValue(),
                                session.getServerSession().isNoBackslashEscapesSet());
                        this.isOnDuplicateKeyUpdate = this.locationOfOnDuplicateKeyUpdate != -1;
                    }
                }

                if (!noBackslashEscapes && c == '\\' && i < (this.statementLength - 1)) {
                    i++;
                    continue; // next character is escaped
                }

                // are we in a quoted identifier? (only valid when the id is not inside a 'string')
                if (!inQuotes && (quotedIdentifierChar != 0) && (c == quotedIdentifierChar)) {
                    inQuotedId = !inQuotedId;
                } else if (!inQuotedId) {
                    //  only respect quotes when not in a quoted identifier

                    if (inQuotes) {
                        if (((c == '\'') || (c == '"')) && c == quoteChar) {
                            if (i < (this.statementLength - 1) && sql.charAt(i + 1) == quoteChar) {
                                i++;
                                continue; // inline quote escape
                            }

                            inQuotes = !inQuotes;
                            quoteChar = 0;
                        } else if (((c == '\'') || (c == '"')) && c == quoteChar) {
                            inQuotes = !inQuotes;
                            quoteChar = 0;
                        }
                    } else {
                        if (c == '#' || (c == '-' && (i + 1) < this.statementLength && sql.charAt(i + 1) == '-')) {
                            // run out to end of statement, or newline, whichever comes first
                            int endOfStmt = this.statementLength - 1;

                            for (; i < endOfStmt; i++) {
                                c = sql.charAt(i);

                                if (c == '\r' || c == '\n') {
                                    break;
                                }
                            }

                            continue;
                        } else if (c == '/' && (i + 1) < this.statementLength) {
                            // Comment?
                            char cNext = sql.charAt(i + 1);

                            if (cNext == '*') {
                                i += 2;

                                for (int j = i; j < this.statementLength; j++) {
                                    i++;
                                    cNext = sql.charAt(j);

                                    if (cNext == '*' && (j + 1) < this.statementLength) {
                                        if (sql.charAt(j + 1) == '/') {
                                            i++;

                                            if (i < this.statementLength) {
                                                c = sql.charAt(i);
                                            }

                                            break; // comment done
                                        }
                                    }
                                }
                            }
                        } else if ((c == '\'') || (c == '"')) {
                            inQuotes = true;
                            quoteChar = c;
                        }
                    }
                }

                if (!inQuotes && !inQuotedId) {
                    if ((c == '?')) {
                        endpointList.add(new int[] { lastParmEnd, i });
                        lastParmEnd = i + 1;

                        if (this.isOnDuplicateKeyUpdate && i > this.locationOfOnDuplicateKeyUpdate) {
                            this.parametersInDuplicateKeyClause = true;
                        }
                    } else if (c == ';') {
                        int j = i + 1;
                        if (j < this.statementLength) {
                            for (; j < this.statementLength; j++) {
                                if (!Character.isWhitespace(sql.charAt(j))) {
                                    break;
                                }
                            }
                            if (j < this.statementLength) {
                                this.numberOfQueries++;
                            }
                            i = j - 1;
                        }
                    }
                }
            }

            if (this.firstStmtChar == 'L') {
                if (StringUtils.startsWithIgnoreCaseAndWs(sql, "LOAD DATA")) {
                    this.foundLoadData = true;
                } else {
                    this.foundLoadData = false;
                }
            } else {
                this.foundLoadData = false;
            }

            endpointList.add(new int[] { lastParmEnd, this.statementLength });
            this.staticSql = new byte[endpointList.size()][];
            this.hasPlaceholders = this.staticSql.length > 1;

            for (i = 0; i < this.staticSql.length; i++) {
                int[] ep = endpointList.get(i);
                int end = ep[1];
                int begin = ep[0];
                int len = end - begin;

                if (this.foundLoadData) {
                    this.staticSql[i] = StringUtils.getBytes(sql, begin, len);
                } else if (encoding == null) {
                    byte[] buf = new byte[len];

                    for (int j = 0; j < len; j++) {
                        buf[j] = (byte) sql.charAt(begin + j);
                    }

                    this.staticSql[i] = buf;
                } else {
                    this.staticSql[i] = StringUtils.getBytes(sql, begin, len, encoding);
                }
            }
        } catch (StringIndexOutOfBoundsException oobEx) {
            throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("PreparedStatement.62", new Object[] { sql }), oobEx,
                    session.getExceptionInterceptor());
        }

        if (buildRewriteInfo) {
            this.canRewriteAsMultiValueInsert = this.numberOfQueries == 1 && !this.parametersInDuplicateKeyClause
                    && canRewrite(sql, this.isOnDuplicateKeyUpdate, this.locationOfOnDuplicateKeyUpdate, this.statementStartPos);
            if (this.canRewriteAsMultiValueInsert && session.getPropertySet().getBooleanProperty(PropertyKey.rewriteBatchedStatements).getValue()) {
                buildRewriteBatchedParams(sql, session, encoding);
            }
        }

    }