use of io.questdb.griffin.engine.functions.SymbolFunction in project questdb by bluestreak01.
the class InSymbolFunctionFactory method newInstance.
@Override
public Function newInstance(int position, ObjList<Function> args, IntList argPositions, CairoConfiguration configuration, SqlExecutionContext sqlExecutionContext) throws SqlException {
CharSequenceHashSet set = new CharSequenceHashSet();
int n = args.size();
if (n == 1) {
return BooleanConstant.FALSE;
}
for (int i = 1; i < n; i++) {
Function func = args.getQuick(i);
switch(ColumnType.tagOf(func.getType())) {
case ColumnType.NULL:
case ColumnType.STRING:
case ColumnType.SYMBOL:
CharSequence value = func.getStr(null);
if (value == null) {
set.add(null);
} else {
set.add(Chars.toString(value));
}
break;
case ColumnType.CHAR:
set.add(String.valueOf(func.getChar(null)));
break;
default:
throw SqlException.$(argPositions.getQuick(i), "STRING constant expected");
}
}
SymbolFunction var = (SymbolFunction) args.getQuick(0);
if (var.isConstant()) {
return BooleanConstant.of(set.contains(var.getSymbol(null)));
}
return new Func(var, set);
}
use of io.questdb.griffin.engine.functions.SymbolFunction in project questdb by bluestreak01.
the class InSymbolCursorFunctionFactory method newInstance.
@Override
public Function newInstance(int position, ObjList<Function> args, IntList argPositions, CairoConfiguration configuration, SqlExecutionContext sqlExecutionContext) throws SqlException {
SymbolFunction symbolFunction = (SymbolFunction) args.getQuick(0);
Function cursorFunction = args.getQuick(1);
// use first column to create list of values (over multiple records)
// supported column types are STRING and SYMBOL
final int zeroColumnType = cursorFunction.getRecordCursorFactory().getMetadata().getColumnType(0);
if (!ColumnType.isSymbolOrString(zeroColumnType)) {
throw SqlException.position(position).put("supported column types are STRING and SYMBOL, found: ").put(ColumnType.nameOf(zeroColumnType));
}
final Record.CharSequenceFunction func = ColumnType.isString(zeroColumnType) ? Record.GET_STR : Record.GET_SYM;
if (symbolFunction.getStaticSymbolTable() != null) {
return new SymbolInCursorFunction(symbolFunction, cursorFunction, func);
}
return new StrInCursorFunction(symbolFunction, cursorFunction, func);
}
use of io.questdb.griffin.engine.functions.SymbolFunction in project questdb by bluestreak01.
the class EqSymCharFunctionFactory method newInstance.
@Override
public Function newInstance(int position, ObjList<Function> args, IntList argPositions, CairoConfiguration configuration, SqlExecutionContext sqlExecutionContext) {
// there are optimisation opportunities
// 1. when one of args is constant null comparison can boil down to checking
// length of non-constant (must be -1)
// 2. when one of arguments is constant, save method call and use a field
SymbolFunction symFunc = (SymbolFunction) args.getQuick(0);
Function chrFunc = args.getQuick(1);
if (chrFunc.isConstant()) {
final char constValue = chrFunc.getChar(null);
if (symFunc.getStaticSymbolTable() != null) {
return new ConstCheckColumnFunc(symFunc, constValue);
} else {
return new ConstCheckFunc(symFunc, constValue);
}
}
return new Func(symFunc, chrFunc);
}
use of io.questdb.griffin.engine.functions.SymbolFunction in project questdb by bluestreak01.
the class EqSymStrFunctionFactory method createHalfConstantFunc.
private Function createHalfConstantFunc(Function constFunc, Function varFunc) {
CharSequence constValue = constFunc.getStr(null);
SymbolFunction func = (SymbolFunction) varFunc;
if (func.getStaticSymbolTable() != null) {
return new ConstCheckColumnFunc(func, constValue);
} else {
if (constValue == null) {
return new NullCheckFunc(varFunc);
}
if (func.isSymbolTableStatic()) {
return new ConstSymIntCheckFunc(func, constValue);
}
return new ConstCheckFunc(func, constValue);
}
}
use of io.questdb.griffin.engine.functions.SymbolFunction in project questdb by bluestreak01.
the class GroupByUtils method prepareGroupByRecordFunctions.
public static void prepareGroupByRecordFunctions(@NotNull QueryModel model, RecordMetadata metadata, @NotNull ListColumnFilter listColumnFilter, ObjList<GroupByFunction> groupByFunctions, @Transient IntList groupByFunctionPositions, ObjList<Function> recordFunctions, @Transient IntList recordFunctionPositions, GenericRecordMetadata groupByMetadata, ArrayColumnTypes keyTypes, int keyColumnIndex, boolean timestampUnimportant, int timestampIndex) throws SqlException {
recordFunctionPositions.clear();
// Process group-by functions first to get the idea of
// how many map values we will have.
// Map value count is needed to calculate offsets for
// map key columns.
ObjList<QueryColumn> columns = model.getColumns();
int valueColumnIndex = 0;
int inferredKeyColumnCount = 0;
// when we have same column several times in a row
// we only add it once to map keys
int lastIndex = -1;
for (int i = 0, n = columns.size(); i < n; i++) {
final QueryColumn column = columns.getQuick(i);
final ExpressionNode node = column.getAst();
final int type;
if (node.type == ExpressionNode.LITERAL) {
// this is key
int index = metadata.getColumnIndexQuiet(node.token);
if (index == -1) {
throw SqlException.invalidColumn(node.position, node.token);
}
type = metadata.getColumnType(index);
if (index != timestampIndex || timestampUnimportant) {
if (lastIndex != index) {
listColumnFilter.add(index + 1);
keyTypes.add(type);
keyColumnIndex++;
lastIndex = index;
}
final Function fun;
switch(ColumnType.tagOf(type)) {
case ColumnType.BOOLEAN:
fun = BooleanColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.BYTE:
fun = ByteColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.SHORT:
fun = ShortColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.CHAR:
fun = CharColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.INT:
fun = IntColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.LONG:
fun = LongColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.FLOAT:
fun = FloatColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.DOUBLE:
fun = DoubleColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.STRING:
fun = StrColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.SYMBOL:
fun = new MapSymbolColumn(keyColumnIndex - 1, index, metadata.isSymbolTableStatic(index));
break;
case ColumnType.DATE:
fun = DateColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.TIMESTAMP:
fun = TimestampColumn.newInstance(keyColumnIndex - 1);
break;
case ColumnType.LONG256:
fun = Long256Column.newInstance(keyColumnIndex - 1);
break;
default:
fun = BinColumn.newInstance(keyColumnIndex - 1);
break;
}
recordFunctions.add(fun);
recordFunctionPositions.add(node.position);
} else {
// set this function to null, cursor will replace it with an instance class
// timestamp function returns value of class member which makes it impossible
// to create these columns in advance of cursor instantiation
recordFunctions.add(null);
groupByFunctionPositions.add(0);
if (groupByMetadata.getTimestampIndex() == -1) {
groupByMetadata.setTimestampIndex(i);
}
assert ColumnType.tagOf(type) == ColumnType.TIMESTAMP;
}
// and finish with populating metadata for this factory
if (column.getAlias() == null) {
groupByMetadata.add(BaseRecordMetadata.copyOf(metadata, index));
} else {
groupByMetadata.add(new TableColumnMetadata(Chars.toString(column.getAlias()), metadata.getColumnHash(index), type, metadata.isColumnIndexed(index), metadata.getIndexValueBlockCapacity(index), metadata.isSymbolTableStatic(index), metadata.getMetadata(index)));
}
inferredKeyColumnCount++;
} else {
// add group-by function as a record function as well
// so it can produce column values
final GroupByFunction groupByFunction = groupByFunctions.getQuick(valueColumnIndex);
recordFunctions.add(groupByFunction);
recordFunctionPositions.add(groupByFunctionPositions.getQuick(valueColumnIndex++));
type = groupByFunction.getType();
// and finish with populating metadata for this factory
groupByMetadata.add(new TableColumnMetadata(Chars.toString(column.getName()), 0, type, false, 0, groupByFunction instanceof SymbolFunction && (((SymbolFunction) groupByFunction).isSymbolTableStatic()), groupByFunction.getMetadata()));
}
}
validateGroupByColumns(model, inferredKeyColumnCount);
}
Aggregations