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;
}
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());
}
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();
}
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);
}
Aggregations