use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class ParserDDL method compileCreateTrigger.
StatementSchema compileCreateTrigger() {
Table table;
boolean isForEachRow = false;
boolean isNowait = false;
boolean hasQueueSize = false;
Integer queueSize = TriggerDef.defaultQueueSize;
String beforeOrAfter;
int beforeOrAfterType;
String operation;
int operationType;
String className;
TriggerDef td;
HsqlName name;
HsqlName otherName = null;
OrderedHashSet columns = null;
int[] updateColumnIndexes = null;
read();
name = readNewSchemaObjectName(SchemaObject.TRIGGER);
switch(token.tokenType) {
case Tokens.INSTEAD:
beforeOrAfter = token.tokenString;
beforeOrAfterType = token.tokenType;
read();
readThis(Tokens.OF);
break;
case Tokens.BEFORE:
case Tokens.AFTER:
beforeOrAfter = token.tokenString;
beforeOrAfterType = token.tokenType;
read();
break;
default:
throw unexpectedToken();
}
switch(token.tokenType) {
case Tokens.INSERT:
case Tokens.DELETE:
operation = token.tokenString;
operationType = token.tokenType;
read();
break;
case Tokens.UPDATE:
operation = token.tokenString;
operationType = token.tokenType;
read();
if (token.tokenType == Tokens.OF && beforeOrAfterType != Tokens.INSTEAD) {
read();
columns = readColumnNames(false);
}
break;
default:
throw unexpectedToken();
}
readThis(Tokens.ON);
table = readTableName();
if (token.tokenType == Tokens.BEFORE) {
read();
checkIsSimpleName();
otherName = readNewSchemaObjectName(SchemaObject.TRIGGER);
}
name.setSchemaIfNull(table.getSchemaName());
checkSchemaUpdateAuthorisation(name.schema);
if (beforeOrAfterType == Tokens.INSTEAD) {
if (!table.isView() || ((View) table).getCheckOption() == SchemaObject.ViewCheckModes.CHECK_CASCADE) {
throw Error.error(ErrorCode.X_42538, name.schema.name);
}
} else {
if (table.isView()) {
throw Error.error(ErrorCode.X_42538, name.schema.name);
}
}
if (name.schema != table.getSchemaName()) {
throw Error.error(ErrorCode.X_42505, name.schema.name);
}
name.parent = table.getName();
database.schemaManager.checkSchemaObjectNotExists(name);
if (columns != null) {
updateColumnIndexes = table.getColumnIndexes(columns);
for (int i = 0; i < updateColumnIndexes.length; i++) {
if (updateColumnIndexes[i] == -1) {
throw Error.error(ErrorCode.X_42544, (String) columns.get(i));
}
}
}
Expression condition = null;
String oldTableName = null;
String newTableName = null;
String oldRowName = null;
String newRowName = null;
Table[] transitions = new Table[4];
RangeVariable[] rangeVars = new RangeVariable[4];
HsqlArrayList compiledStatements = new HsqlArrayList();
String conditionSQL = null;
String procedureSQL = null;
if (token.tokenType == Tokens.REFERENCING) {
read();
if (token.tokenType != Tokens.OLD && token.tokenType != Tokens.NEW) {
throw unexpectedToken();
}
while (true) {
if (token.tokenType == Tokens.OLD) {
if (operationType == Tokens.INSERT) {
throw unexpectedToken();
}
read();
if (token.tokenType == Tokens.TABLE) {
if (oldTableName != null || beforeOrAfterType == Tokens.BEFORE) {
throw unexpectedToken();
}
read();
readIfThis(Tokens.AS);
checkIsSimpleName();
oldTableName = token.tokenString;
String n = oldTableName;
if (n.equals(newTableName) || n.equals(oldRowName) || n.equals(newRowName)) {
throw unexpectedToken();
}
HsqlName hsqlName = database.nameManager.newHsqlName(table.getSchemaName(), n, isDelimitedIdentifier(), SchemaObject.TRANSITION);
Table transition = new Table(table, hsqlName);
RangeVariable range = new RangeVariable(transition, null, null, null, compileContext);
transitions[TriggerDef.OLD_TABLE] = transition;
rangeVars[TriggerDef.OLD_TABLE] = range;
} else if (token.tokenType == Tokens.ROW) {
if (oldRowName != null) {
throw unexpectedToken();
}
read();
readIfThis(Tokens.AS);
checkIsSimpleName();
oldRowName = token.tokenString;
String n = oldRowName;
if (n.equals(newTableName) || n.equals(oldTableName) || n.equals(newRowName)) {
throw unexpectedToken();
}
isForEachRow = true;
HsqlName hsqlName = database.nameManager.newHsqlName(table.getSchemaName(), n, isDelimitedIdentifier(), SchemaObject.TRANSITION);
Table transition = new Table(table, hsqlName);
RangeVariable range = new RangeVariable(transition, null, null, null, compileContext);
transitions[TriggerDef.OLD_ROW] = transition;
rangeVars[TriggerDef.OLD_ROW] = range;
} else {
throw unexpectedToken();
}
} else if (token.tokenType == Tokens.NEW) {
if (operationType == Tokens.DELETE) {
throw unexpectedToken();
}
read();
if (token.tokenType == Tokens.TABLE) {
if (newTableName != null || beforeOrAfterType == Tokens.BEFORE) {
throw unexpectedToken();
}
read();
readIfThis(Tokens.AS);
checkIsSimpleName();
newTableName = token.tokenString;
String n = newTableName;
if (n.equals(oldTableName) || n.equals(oldRowName) || n.equals(newRowName)) {
throw unexpectedToken();
}
HsqlName hsqlName = database.nameManager.newHsqlName(table.getSchemaName(), n, isDelimitedIdentifier(), SchemaObject.TRANSITION);
Table transition = new Table(table, hsqlName);
RangeVariable range = new RangeVariable(transition, null, null, null, compileContext);
transitions[TriggerDef.NEW_TABLE] = transition;
rangeVars[TriggerDef.NEW_TABLE] = range;
} else if (token.tokenType == Tokens.ROW) {
if (newRowName != null) {
throw unexpectedToken();
}
read();
readIfThis(Tokens.AS);
checkIsSimpleName();
newRowName = token.tokenString;
isForEachRow = true;
String n = newRowName;
if (n.equals(oldTableName) || n.equals(newTableName) || n.equals(oldRowName)) {
throw unexpectedToken();
}
HsqlName hsqlName = database.nameManager.newHsqlName(table.getSchemaName(), n, isDelimitedIdentifier(), SchemaObject.TRANSITION);
Table transition = new Table(table, hsqlName);
RangeVariable range = new RangeVariable(transition, null, null, null, compileContext);
transitions[TriggerDef.NEW_ROW] = transition;
rangeVars[TriggerDef.NEW_ROW] = range;
} else {
throw unexpectedToken();
}
} else {
break;
}
read();
}
}
if (isForEachRow && token.tokenType != Tokens.FOR) {
throw unexpectedToken();
}
// "FOR EACH ROW" or "CALL"
if (token.tokenType == Tokens.FOR) {
read();
readThis(Tokens.EACH);
if (token.tokenType == Tokens.ROW) {
isForEachRow = true;
} else if (token.tokenType == Tokens.STATEMENT) {
if (isForEachRow) {
throw unexpectedToken();
}
} else {
throw unexpectedToken();
}
read();
}
//
if (rangeVars[TriggerDef.OLD_TABLE] != null) {
}
if (rangeVars[TriggerDef.NEW_TABLE] != null) {
}
//
if (Tokens.T_NOWAIT.equals(token.tokenString)) {
read();
isNowait = true;
} else if (Tokens.T_QUEUE.equals(token.tokenString)) {
read();
queueSize = readInteger();
hasQueueSize = true;
}
if (token.tokenType == Tokens.WHEN && beforeOrAfterType != Tokens.INSTEAD) {
read();
readThis(Tokens.OPENBRACKET);
int position = getPosition();
isCheckOrTriggerCondition = true;
condition = XreadBooleanValueExpression();
conditionSQL = getLastPart(position);
isCheckOrTriggerCondition = false;
readThis(Tokens.CLOSEBRACKET);
HsqlList unresolved = condition.resolveColumnReferences(rangeVars, null);
ExpressionColumn.checkColumnsResolved(unresolved);
condition.resolveTypes(session, null);
if (condition.getDataType() != Type.SQL_BOOLEAN) {
throw Error.error(ErrorCode.X_42568);
}
}
if (token.tokenType == Tokens.CALL) {
read();
checkIsSimpleName();
checkIsDelimitedIdentifier();
className = token.tokenString;
read();
td = new TriggerDef(name, beforeOrAfter, operation, isForEachRow, table, transitions, rangeVars, condition, conditionSQL, updateColumnIndexes, className, isNowait, queueSize);
String sql = getLastPart();
Object[] args = new Object[] { td, otherName };
return new StatementSchema(sql, StatementTypes.CREATE_TRIGGER, args, null, table.getName());
}
//
if (isNowait) {
throw unexpectedToken(Tokens.T_NOWAIT);
}
if (hasQueueSize) {
throw unexpectedToken(Tokens.T_QUEUE);
}
// procedure
boolean isBlock = false;
if (readIfThis(Tokens.BEGIN)) {
readThis(Tokens.ATOMIC);
isBlock = true;
}
int position = getPosition();
while (true) {
StatementDMQL cs = null;
switch(token.tokenType) {
case Tokens.INSERT:
if (beforeOrAfterType == Tokens.BEFORE) {
throw unexpectedToken();
}
cs = compileInsertStatement(rangeVars);
compiledStatements.add(cs);
if (isBlock) {
readThis(Tokens.SEMICOLON);
}
break;
case Tokens.UPDATE:
if (beforeOrAfterType == Tokens.BEFORE) {
throw unexpectedToken();
}
cs = compileUpdateStatement(rangeVars);
compiledStatements.add(cs);
if (isBlock) {
readThis(Tokens.SEMICOLON);
}
break;
case Tokens.DELETE:
if (beforeOrAfterType == Tokens.BEFORE) {
throw unexpectedToken();
}
cs = compileDeleteStatement(rangeVars);
compiledStatements.add(cs);
if (isBlock) {
readThis(Tokens.SEMICOLON);
}
break;
case Tokens.MERGE:
if (beforeOrAfterType == Tokens.BEFORE) {
throw unexpectedToken();
}
cs = compileMergeStatement(rangeVars);
compiledStatements.add(cs);
if (isBlock) {
readThis(Tokens.SEMICOLON);
}
break;
case Tokens.SET:
if (beforeOrAfterType != Tokens.BEFORE || operationType == Tokens.DELETE) {
throw unexpectedToken();
}
cs = compileTriggerSetStatement(table, rangeVars);
compiledStatements.add(cs);
if (isBlock) {
readThis(Tokens.SEMICOLON);
}
break;
case Tokens.END:
break;
default:
throw unexpectedToken();
}
if (!isBlock || token.tokenType == Tokens.END) {
break;
}
}
procedureSQL = getLastPart(position);
if (isBlock) {
readThis(Tokens.END);
}
StatementDMQL[] csArray = new StatementDMQL[compiledStatements.size()];
compiledStatements.toArray(csArray);
OrderedHashSet references = compileContext.getSchemaObjectNames();
for (int i = 0; i < csArray.length; i++) {
Table targetTable = csArray[i].targetTable;
boolean[] check = csArray[i].getInsertOrUpdateColumnCheckList();
if (check != null) {
targetTable.getColumnNames(check, references);
}
}
references.remove(table.getName());
td = new TriggerDefSQL(name, beforeOrAfter, operation, isForEachRow, table, transitions, rangeVars, condition, conditionSQL, updateColumnIndexes, csArray, procedureSQL, references);
String sql = getLastPart();
Object[] args = new Object[] { td, otherName };
return new StatementSchema(sql, StatementTypes.CREATE_TRIGGER, args, null, table.getName());
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class ParserDML method compileDeleteStatement.
/**
* Creates a DELETE-type Statement from this parse context.
*/
StatementDMQL compileDeleteStatement(RangeVariable[] outerRanges) {
Expression condition = null;
boolean truncate = false;
boolean restartIdentity = false;
switch(token.tokenType) {
case Tokens.TRUNCATE:
{
read();
readThis(Tokens.TABLE);
truncate = true;
break;
}
case Tokens.DELETE:
{
read();
readThis(Tokens.FROM);
break;
}
}
RangeVariable[] rangeVariables = { readSimpleRangeVariable(StatementTypes.DELETE_WHERE) };
Table table = rangeVariables[0].getTable();
Table baseTable = table.getBaseTable();
if (truncate) {
switch(token.tokenType) {
case Tokens.CONTINUE:
{
read();
readThis(Tokens.IDENTITY);
break;
}
case Tokens.RESTART:
{
read();
readThis(Tokens.IDENTITY);
restartIdentity = true;
break;
}
}
for (int i = 0; i < table.constraintList.length; i++) {
if (table.constraintList[i].getConstraintType() == Constraint.MAIN) {
throw Error.error(ErrorCode.X_23501);
}
}
}
if (truncate && table != baseTable) {
throw Error.error(ErrorCode.X_42000);
}
if (!truncate && token.tokenType == Tokens.WHERE) {
read();
condition = XreadBooleanValueExpression();
HsqlList unresolved = condition.resolveColumnReferences(outerRanges, null);
unresolved = Expression.resolveColumnSet(rangeVariables, unresolved, null);
ExpressionColumn.checkColumnsResolved(unresolved);
condition.resolveTypes(session, null);
if (condition.isParam()) {
condition.dataType = Type.SQL_BOOLEAN;
}
if (condition.getDataType() != Type.SQL_BOOLEAN) {
throw Error.error(ErrorCode.X_42568);
}
}
// baseTable could be null for stream views.
if (baseTable != null && table != baseTable) {
QuerySpecification select = ((TableDerived) table).getQueryExpression().getMainSelect();
if (condition != null) {
condition = condition.replaceColumnReferences(rangeVariables[0], select.exprColumns);
}
rangeVariables[0] = new RangeVariable(select.rangeVariables[0]);
condition = ExpressionLogical.andExpressions(select.queryCondition, condition);
}
if (condition != null) {
RangeVariableResolver resolver = new RangeVariableResolver(rangeVariables, condition, compileContext);
resolver.processConditions();
rangeVariables = resolver.rangeVariables;
}
// VoltDB Extension:
// This needs to be done before building the compiled statement
// so that parameters in LIMIT or OFFSET are retrieved from
// the compileContext
SortAndSlice sas = voltGetSortAndSliceForDelete(rangeVariables);
StatementDMQL cs = new StatementDML(session, table, rangeVariables, compileContext, restartIdentity);
// VoltDB Extension:
voltAppendDeleteSortAndSlice((StatementDML) cs, sas);
return cs;
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class ParserDML method resolveUpdateExpressions.
void resolveUpdateExpressions(Table targetTable, RangeVariable[] rangeVariables, int[] columnMap, Expression[] colExpressions, RangeVariable[] outerRanges) {
HsqlList unresolved = null;
int enforcedDefaultIndex = -1;
if (targetTable.hasIdentityColumn() && targetTable.identitySequence.isAlways()) {
enforcedDefaultIndex = targetTable.getIdentityColumnIndex();
}
for (int i = 0, ix = 0; i < columnMap.length; ix++) {
Expression expr = colExpressions[ix];
Expression e;
if (expr.getType() == OpTypes.ROW) {
Expression[] elements = expr.nodes;
for (int j = 0; j < elements.length; j++, i++) {
e = elements[j];
if (enforcedDefaultIndex == columnMap[i]) {
if (e.getType() != OpTypes.DEFAULT) {
throw Error.error(ErrorCode.X_42541);
}
}
if (e.isParam()) {
e.setAttributesAsColumn(targetTable.getColumn(columnMap[i]), true);
} else if (e.getType() == OpTypes.DEFAULT) {
if (targetTable.colDefaults[columnMap[i]] == null && targetTable.identityColumn != columnMap[i]) {
throw Error.error(ErrorCode.X_42544);
}
} else {
unresolved = expr.resolveColumnReferences(outerRanges, null);
unresolved = Expression.resolveColumnSet(rangeVariables, unresolved, null);
ExpressionColumn.checkColumnsResolved(unresolved);
unresolved = null;
e.resolveTypes(session, null);
}
}
} else if (expr.getType() == OpTypes.TABLE_SUBQUERY) {
unresolved = expr.resolveColumnReferences(outerRanges, null);
unresolved = Expression.resolveColumnSet(rangeVariables, unresolved, null);
ExpressionColumn.checkColumnsResolved(unresolved);
expr.resolveTypes(session, null);
int count = expr.subQuery.queryExpression.getColumnCount();
for (int j = 0; j < count; j++, i++) {
if (enforcedDefaultIndex == columnMap[i]) {
throw Error.error(ErrorCode.X_42541);
}
}
} else {
e = expr;
if (enforcedDefaultIndex == columnMap[i]) {
if (e.getType() != OpTypes.DEFAULT) {
throw Error.error(ErrorCode.X_42541);
}
}
if (e.isParam()) {
e.setAttributesAsColumn(targetTable.getColumn(columnMap[i]), true);
} else if (e.getType() == OpTypes.DEFAULT) {
if (targetTable.colDefaults[columnMap[i]] == null && targetTable.identityColumn != columnMap[i]) {
throw Error.error(ErrorCode.X_42544);
}
} else {
unresolved = expr.resolveColumnReferences(outerRanges, null);
unresolved = Expression.resolveColumnSet(rangeVariables, unresolved, null);
ExpressionColumn.checkColumnsResolved(unresolved);
e.resolveTypes(session, null);
}
i++;
}
}
/* Disabled for ENG-11832
if (!targetTable.isView) {
return;
}
QuerySpecification select =
((TableDerived) targetTable).getQueryExpression().getMainSelect();
for (int i = 0; i < colExpressions.length; i++) {
colExpressions[i] =
colExpressions[i].replaceColumnReferences(rangeVariables[0],
select.exprColumns);
}
*/
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class ParserDML method compileMergeStatement.
/**
* Retrieves a MERGE Statement from this parse context.
*/
StatementDMQL compileMergeStatement(RangeVariable[] outerRanges) {
boolean[] insertColumnCheckList;
int[] insertColumnMap = null;
int[] updateColumnMap = null;
int[] baseUpdateColumnMap;
Table table;
RangeVariable targetRange;
RangeVariable sourceRange;
Expression mergeCondition;
HsqlArrayList updateList = new HsqlArrayList();
Expression[] updateExpressions = null;
HsqlArrayList insertList = new HsqlArrayList();
Expression insertExpression = null;
read();
readThis(Tokens.INTO);
targetRange = readSimpleRangeVariable(StatementTypes.MERGE);
table = targetRange.rangeTable;
readThis(Tokens.USING);
sourceRange = readTableOrSubquery();
// parse ON search conditions
readThis(Tokens.ON);
mergeCondition = XreadBooleanValueExpression();
if (mergeCondition.getDataType() != Type.SQL_BOOLEAN) {
throw Error.error(ErrorCode.X_42568);
}
RangeVariable[] fullRangeVars = new RangeVariable[] { sourceRange, targetRange };
RangeVariable[] sourceRangeVars = new RangeVariable[] { sourceRange };
RangeVariable[] targetRangeVars = new RangeVariable[] { targetRange };
// parse WHEN clause(s) and convert lists to arrays
insertColumnMap = table.getColumnMap();
insertColumnCheckList = table.getNewColumnCheckList();
OrderedHashSet updateColNames = new OrderedHashSet();
OrderedHashSet insertColNames = new OrderedHashSet();
readMergeWhen(insertColNames, updateColNames, insertList, updateList, targetRangeVars, sourceRange);
if (insertList.size() > 0) {
int colCount = insertColNames.size();
if (colCount != 0) {
insertColumnMap = table.getColumnIndexes(insertColNames);
insertColumnCheckList = table.getColumnCheckList(insertColumnMap);
}
insertExpression = (Expression) insertList.get(0);
setParameterTypes(insertExpression, table, insertColumnMap);
}
if (updateList.size() > 0) {
updateExpressions = new Expression[updateList.size()];
updateList.toArray(updateExpressions);
updateColumnMap = table.getColumnIndexes(updateColNames);
}
if (updateExpressions != null) {
Table baseTable = table.getBaseTable();
baseUpdateColumnMap = updateColumnMap;
if (table != baseTable) {
baseUpdateColumnMap = new int[updateColumnMap.length];
ArrayUtil.projectRow(table.getBaseTableColumnMap(), updateColumnMap, baseUpdateColumnMap);
}
resolveUpdateExpressions(table, sourceRangeVars, updateColumnMap, updateExpressions, outerRanges);
}
HsqlList unresolved = null;
unresolved = mergeCondition.resolveColumnReferences(fullRangeVars, null);
ExpressionColumn.checkColumnsResolved(unresolved);
mergeCondition.resolveTypes(session, null);
if (mergeCondition.isParam()) {
mergeCondition.dataType = Type.SQL_BOOLEAN;
}
if (mergeCondition.getDataType() != Type.SQL_BOOLEAN) {
throw Error.error(ErrorCode.X_42568);
}
RangeVariableResolver resolver = new RangeVariableResolver(fullRangeVars, mergeCondition, compileContext);
resolver.processConditions();
fullRangeVars = resolver.rangeVariables;
if (insertExpression != null) {
unresolved = insertExpression.resolveColumnReferences(sourceRangeVars, unresolved);
ExpressionColumn.checkColumnsResolved(unresolved);
insertExpression.resolveTypes(session, null);
}
StatementDMQL cs = new StatementDML(session, fullRangeVars, insertColumnMap, updateColumnMap, insertColumnCheckList, mergeCondition, insertExpression, updateExpressions, compileContext);
return cs;
}
use of org.hsqldb_voltpatches.lib.HsqlList in project voltdb by VoltDB.
the class ParserDML method voltGetSortAndSliceForDelete.
/************************* Volt DB Extensions *************************/
/**
* This is a Volt extension to allow
* DELETE FROM tab ORDER BY c LIMIT 1
* Adds a SortAndSlice object to the statement if the next tokens
* are ORDER BY, LIMIT or OFFSET.
* @param deleteStmt
*/
private SortAndSlice voltGetSortAndSliceForDelete(RangeVariable[] rangeVariables) {
SortAndSlice sas = XreadOrderByExpression();
if (sas == null || sas == SortAndSlice.noSort)
return SortAndSlice.noSort;
// from how compileDelete resolves columns in its WHERE clause
for (int i = 0; i < sas.exprList.size(); ++i) {
Expression e = (Expression) sas.exprList.get(i);
HsqlList unresolved = e.resolveColumnReferences(RangeVariable.emptyArray, null);
unresolved = Expression.resolveColumnSet(rangeVariables, unresolved, null);
ExpressionColumn.checkColumnsResolved(unresolved);
e.resolveTypes(session, null);
}
return sas;
}
Aggregations