Search in sources :

Example 1 with ValueNumber

use of lucee.runtime.sql.exp.value.ValueNumber in project Lucee by lucee.

the class SelectParser method parse.

// select <select-statement> from <tables> where <where-statement>
public Selects parse(String sql) throws SQLParserException {
    columnIndex = 0;
    ParserString raw = new ParserString(sql.trim());
    Selects selects = new Selects();
    Select select = new Select();
    boolean runAgain = false;
    do {
        // select
        if (!raw.forwardIfCurrentAndNoWordNumberAfter("select"))
            throw new SQLParserException("missing select");
        raw.removeSpace();
        // top
        if (raw.forwardIfCurrentAndNoWordNumberAfter("top")) {
            raw.removeSpace();
            ValueNumber number = number(raw);
            if (number == null)
                throw new SQLParserException("missing top number");
            select.setTop(number);
            raw.removeSpace();
        }
        // distinct
        if (raw.forwardIfCurrentAndNoWordNumberAfter("distinct")) {
            select.setDistinct(true);
            raw.removeSpace();
        }
        // all
        if (raw.forwardIfCurrentAndNoWordNumberAfter("all")) {
            select.setDistinct(false);
            raw.removeSpace();
        }
        // select expression
        selectExpressions(raw, select);
        raw.removeSpace();
        // from
        if (!raw.forwardIfCurrentAndNoWordNumberAfter("from"))
            throw new SQLParserException("missing from");
        tableList(raw, select);
        raw.removeSpace();
        // where
        if (raw.forwardIfCurrentAndNoWordNumberAfter("where"))
            whereExpressions(raw, select);
        raw.removeSpace();
        // group by
        if (raw.forwardIfCurrentAndNoWordNumberAfter("group by")) {
            groupByExpressions(raw, select);
            raw.removeSpace();
            // having
            if (raw.forwardIfCurrentAndNoWordNumberAfter("having"))
                havingExpressions(raw, select);
            raw.removeSpace();
        }
        selects.addSelect(select);
        runAgain = false;
        // union
        if (raw.forwardIfCurrentAndNoWordNumberAfter("union")) {
            select = new Select();
            raw.removeSpace();
            if (raw.forwardIfCurrentAndNoWordNumberAfter("all")) {
                raw.removeSpace();
                select.setUnionDistinct(false);
            } else if (raw.forwardIfCurrentAndNoWordNumberAfter("distinct")) {
                raw.removeSpace();
                select.setUnionDistinct(true);
            } else
                select.setDistinct(true);
            raw.removeSpace();
            runAgain = true;
        }
    } while (runAgain);
    // order by
    if (raw.forwardIfCurrentAndNoWordNumberAfter("order by"))
        orderByExpressions(raw, selects);
    raw.removeSpace();
    if (raw.forwardIfCurrent(';'))
        raw.removeSpace();
    if (!raw.isAfterLast())
        throw new SQLParserException("can not read the full sql statement (stop at:" + raw.getCurrent() + ")");
    return selects;
}
Also used : ParserString(lucee.commons.lang.ParserString) ValueNumber(lucee.runtime.sql.exp.value.ValueNumber)

Example 2 with ValueNumber

use of lucee.runtime.sql.exp.value.ValueNumber in project Lucee by lucee.

the class SelectParser method number.

private ValueNumber number(ParserString raw) throws SQLParserException {
    // check first character is a number literal representation
    if (!(raw.isCurrentBetween('0', '9') || raw.isCurrent('.')))
        return null;
    StringBuffer rtn = new StringBuffer();
    // get digit on the left site of the dot
    if (raw.isCurrent('.'))
        rtn.append('0');
    else
        rtn.append(digit(raw));
    // read dot if exist
    if (raw.forwardIfCurrent('.')) {
        rtn.append('.');
        String rightSite = digit(raw);
        if (rightSite.length() > 0 && raw.forwardIfCurrent('e')) {
            if (raw.isCurrentBetween('0', '9')) {
                rightSite += 'e' + digit(raw);
            } else {
                raw.previous();
            }
        }
        // read right side of the dot
        if (rightSite.length() == 0)
            throw new SQLParserException("Number can't end with [.]");
        rtn.append(rightSite);
    }
    raw.removeSpace();
    return new ValueNumber(rtn.toString());
}
Also used : ValueNumber(lucee.runtime.sql.exp.value.ValueNumber) ParserString(lucee.commons.lang.ParserString) ValueString(lucee.runtime.sql.exp.value.ValueString)

Example 3 with ValueNumber

use of lucee.runtime.sql.exp.value.ValueNumber in project Lucee by lucee.

the class Selects method _toString.

public static String _toString(Selects __selects) {
    Select[] _selects = __selects.getSelects();
    Select s;
    StringBuffer sb = new StringBuffer();
    for (int y = 0; y < _selects.length; y++) {
        s = _selects[y];
        if (y > 0) {
            if (s.isUnionDistinct())
                sb.append("union distinct\n\n");
            else
                sb.append("union\n\n");
        }
        sb.append("select\n\t");
        if (s.isDistinct())
            sb.append("distinct\n\t");
        ValueNumber top = s.getTop();
        if (top != null)
            sb.append("top " + top.getString() + "\n\t");
        // select
        Expression[] sels = s.getSelects();
        Expression exp;
        boolean first = true;
        for (int i = 0; i < sels.length; i++) {
            if (!first)
                sb.append("\t,");
            exp = sels[i];
            sb.append(exp.toString(false) + "\n");
            first = false;
        }
        // from
        sb.append("from\n\t");
        Column[] forms = s.getFroms();
        first = true;
        for (int i = 0; i < forms.length; i++) {
            if (!first)
                sb.append("\t,");
            exp = forms[i];
            sb.append(exp.toString(false) + "\n");
            first = false;
        }
        // where
        if (s.getWhere() != null) {
            sb.append("where \n\t");
            sb.append(s.getWhere().toString(true));
            sb.append("\n");
        }
        // group by
        Column[] gbs = s.getGroupbys();
        if (gbs.length > 0) {
            sb.append("group by\n\t");
            first = true;
            for (int i = 0; i < gbs.length; i++) {
                if (!first)
                    sb.append("\t,");
                exp = gbs[i];
                sb.append(exp.toString(false) + "\n");
                first = false;
            }
        }
        // having
        Operation having = s.getHaving();
        if (having != null) {
            sb.append("having \n\t");
            sb.append(having.toString(true));
            sb.append("\n");
        }
    }
    // order by
    if (__selects.orderbys != null && __selects.orderbys.size() > 0) {
        sb.append("order by\n\t");
        Iterator<Column> it = __selects.orderbys.iterator();
        Expression exp;
        boolean first = true;
        while (it.hasNext()) {
            if (!first)
                sb.append("\t,");
            exp = it.next();
            sb.append(exp.toString(false) + " " + (exp.isDirectionBackward() ? "DESC" : "ASC") + "\n");
            first = false;
        }
    }
    return sb.toString();
}
Also used : Expression(lucee.runtime.sql.exp.Expression) Column(lucee.runtime.sql.exp.Column) ValueNumber(lucee.runtime.sql.exp.value.ValueNumber) Operation(lucee.runtime.sql.exp.op.Operation)

Example 4 with ValueNumber

use of lucee.runtime.sql.exp.value.ValueNumber in project Lucee by lucee.

the class QoQ method executeSingle.

private void executeSingle(PageContext pc, Select select, Query qr, QueryImpl target, int maxrows, SQL sql, boolean hasOrders) throws PageException {
    ValueNumber oTop = select.getTop();
    if (oTop != null) {
        int top = (int) oTop.getValueAsDouble();
        if (maxrows == -1 || maxrows > top)
            maxrows = top;
    }
    int recCount = qr.getRecordcount();
    Expression[] expSelects = select.getSelects();
    int selCount = expSelects.length;
    Map<Collection.Key, Object> selects = new HashMap<Collection.Key, Object>();
    Iterator<Key> it;
    Key k;
    // headers
    for (int i = 0; i < selCount; i++) {
        Expression expSelect = expSelects[i];
        if (expSelect.getAlias().equals("*")) {
            it = qr.keyIterator();
            while (it.hasNext()) {
                k = it.next();
                selects.put(k, k);
                queryAddColumn(target, k, qr.getColumn(k).getType());
            }
        } else {
            Key alias = Caster.toKey(expSelect.getAlias());
            selects.put(alias, expSelect);
            int type = Types.OTHER;
            if (expSelect instanceof ColumnExpression)
                type = qr.getColumn(Caster.toKey(((ColumnExpression) expSelect).getColumnName())).getType();
            queryAddColumn(target, alias, type);
        }
    }
    Collection.Key[] headers = selects.keySet().toArray(new Collection.Key[selects.size()]);
    // loop records
    Operation where = select.getWhere();
    boolean hasMaxrow = maxrows > -1 && !hasOrders;
    // get target columns
    QueryColumn[] trgColumns = new QueryColumn[headers.length];
    Object[] trgValues = new Object[headers.length];
    for (int cell = 0; cell < headers.length; cell++) {
        trgColumns[cell] = target.getColumn(headers[cell]);
        trgValues[cell] = selects.get(headers[cell]);
    }
    for (int row = 1; row <= recCount; row++) {
        sql.setPosition(0);
        if (hasMaxrow && maxrows <= target.getRecordcount())
            break;
        boolean useRow = where == null || Caster.toBooleanValue(executeExp(pc, sql, qr, where, row));
        if (useRow) {
            target.addRow(1);
            for (int cell = 0; cell < headers.length; cell++) {
                // Object value = selects.get(headers[cell]);
                trgColumns[cell].set(target.getRecordcount(), getValue(pc, sql, qr, row, headers[cell], trgValues[cell]));
            /*target.setAt(
							headers[cell],
							target.getRecordcount(),
							getValue(pc,sql,qr,row,headers[cell],trgValues[cell])
						);*/
            }
        }
    }
    // Group By
    if (select.getGroupbys().length > 0)
        throw new DatabaseException("group by are not supported at the moment", null, sql, null);
    if (select.getHaving() != null)
        throw new DatabaseException("having is not supported at the moment", null, sql, null);
}
Also used : HashMap(java.util.HashMap) Operation(lucee.runtime.sql.exp.op.Operation) BracketExpression(lucee.runtime.sql.exp.BracketExpression) ColumnExpression(lucee.runtime.sql.exp.ColumnExpression) Expression(lucee.runtime.sql.exp.Expression) ColumnExpression(lucee.runtime.sql.exp.ColumnExpression) QueryColumn(lucee.runtime.type.QueryColumn) ValueNumber(lucee.runtime.sql.exp.value.ValueNumber) Collection(lucee.runtime.type.Collection) DatabaseException(lucee.runtime.exp.DatabaseException) Key(lucee.runtime.type.Collection.Key)

Aggregations

ValueNumber (lucee.runtime.sql.exp.value.ValueNumber)4 ParserString (lucee.commons.lang.ParserString)2 Expression (lucee.runtime.sql.exp.Expression)2 Operation (lucee.runtime.sql.exp.op.Operation)2 HashMap (java.util.HashMap)1 DatabaseException (lucee.runtime.exp.DatabaseException)1 BracketExpression (lucee.runtime.sql.exp.BracketExpression)1 Column (lucee.runtime.sql.exp.Column)1 ColumnExpression (lucee.runtime.sql.exp.ColumnExpression)1 ValueString (lucee.runtime.sql.exp.value.ValueString)1 Collection (lucee.runtime.type.Collection)1 Key (lucee.runtime.type.Collection.Key)1 QueryColumn (lucee.runtime.type.QueryColumn)1