public void rename(String name, boolean isquoted) { if (manager.sqlRegularNames && name.length() > 128) { throw Error.error(ErrorCode.X_42501, name); } // get rid of the excess this.name = new String(name); this.statementName = this.name; this.isNameQuoted = isquoted; if (isNameQuoted) { statementName = StringConverter.toQuotedString(name, '"', true); } if (name.startsWith("SYS_")) { int length = name.lastIndexOf('_') + 1; try { int temp = Integer.parseInt(name.substring(length)); if (temp > manager.sysNumber) { manager.sysNumber = temp; } } catch (NumberFormatException e) { } } }
public static void addAutoColumns(Table paramTable, Type[] paramArrayOfType) { for (int i = 0; i < paramArrayOfType.length; i++) { ColumnSchema localColumnSchema = new ColumnSchema( HsqlNameManager.getAutoColumnName(i), paramArrayOfType[i], true, false, null); paramTable.addColumnNoCheck(localColumnSchema); } }
static { for (int i = 0; i < diagnosticsVariableTokens.length; i++) { HsqlName name = HsqlNameManager.newSystemObjectName(diagnosticsVariableTokens[i], SchemaObject.VARIABLE); Type type = Type.SQL_INTEGER; if (diagnosticsVariableTokens[i] == Tokens.T_MORE) { type = Type.SQL_CHAR; } ColumnSchema col = new ColumnSchema(name, type, false, false, null); diagnosticsList.add(diagnosticsVariableTokens[i], col); } }
public void setRegularNames(boolean mode) { sqlRegularNames = mode; nameManager.setSqlRegularNames(mode); }
public HsqlName getCatalogName() { return nameManager.getCatalogName(); }
/** * Implementation of column, variable, parameter, etc. access operations. * * @author Fred Toussi (fredt@users dot sourceforge.net) * @version 2.2.9 * @since 1.9.0 */ public class ExpressionColumn extends Expression { public static final ExpressionColumn[] emptyArray = new ExpressionColumn[] {}; static final SimpleName rownumName = HsqlNameManager.getSimpleName("ROWNUM", false); // public static final HashMappedList diagnosticsList = new HashMappedList(); static final String[] diagnosticsVariableTokens = new String[] {Tokens.T_NUMBER, Tokens.T_MORE, Tokens.T_ROW_COUNT}; public static final int idx_number = 0; public static final int idx_more = 1; public static final int idx_row_count = 2; static { for (int i = 0; i < diagnosticsVariableTokens.length; i++) { HsqlName name = HsqlNameManager.newSystemObjectName(diagnosticsVariableTokens[i], SchemaObject.VARIABLE); Type type = Type.SQL_INTEGER; if (diagnosticsVariableTokens[i] == Tokens.T_MORE) { type = Type.SQL_CHAR; } ColumnSchema col = new ColumnSchema(name, type, false, false, null); diagnosticsList.add(diagnosticsVariableTokens[i], col); } } // ColumnSchema column; String schema; String tableName; String columnName; RangeVariable rangeVariable; // NumberSequence sequence; boolean isWritable; // = false; true if column of writable table // boolean isParam; // /** Creates a OpTypes.COLUMN expression */ ExpressionColumn(String schema, String table, String column) { super(OpTypes.COLUMN); this.schema = schema; this.tableName = table; this.columnName = column; } ExpressionColumn(ColumnSchema column) { super(OpTypes.COLUMN); this.column = column; this.dataType = column.getDataType(); columnName = column.getName().name; } ExpressionColumn(RangeVariable rangeVar, int index) { super(OpTypes.COLUMN); columnIndex = index; setAutoAttributesAsColumn(rangeVar, columnIndex); } /** Creates a temporary OpTypes.COLUMN expression */ ExpressionColumn(Expression e, int colIndex, int rangePosition) { super(OpTypes.SIMPLE_COLUMN); dataType = e.dataType; columnIndex = colIndex; alias = e.alias; this.rangePosition = rangePosition; } ExpressionColumn() { super(OpTypes.ASTERISK); } ExpressionColumn(int type) { super(type); if (type == OpTypes.DYNAMIC_PARAM) { isParam = true; } else if (type == OpTypes.ROWNUM) { columnName = rownumName.name; dataType = Type.SQL_INTEGER; } } /** For diagnostics vars */ ExpressionColumn(int type, int columnIndex) { super(type); this.column = (ColumnSchema) diagnosticsList.get(columnIndex); this.columnIndex = columnIndex; this.dataType = column.dataType; } ExpressionColumn(Expression[] nodes, String name) { super(OpTypes.COALESCE); this.nodes = nodes; this.columnName = name; } /** Creates an OpCodes.ASTERISK expression */ ExpressionColumn(String schema, String table) { super(OpTypes.MULTICOLUMN); this.schema = schema; tableName = table; } /** Creates a OpTypes.SEQUENCE expression */ ExpressionColumn(NumberSequence sequence, int opType) { super(opType); this.sequence = sequence; dataType = sequence.getDataType(); } void setAutoAttributesAsColumn(RangeVariable range, int i) { columnIndex = i; column = range.getColumn(i); dataType = column.getDataType(); columnName = range.getColumnAlias(i).name; tableName = range.getTableAlias().name; rangeVariable = range; rangeVariable.addColumn(columnIndex); } void setAttributesAsColumn(RangeVariable range, int i) { columnIndex = i; column = range.getColumn(i); dataType = column.getDataType(); rangeVariable = range; if (range.rangeType == RangeVariable.TABLE_RANGE) { rangeVariable.addColumn(columnIndex); } } public byte getNullability() { switch (opType) { case OpTypes.COLUMN: return column.getNullability(); case OpTypes.SEQUENCE: case OpTypes.COALESCE: case OpTypes.ROWNUM: return SchemaObject.Nullability.NO_NULLS; default: return SchemaObject.Nullability.NULLABLE_UNKNOWN; } } void setAttributesAsColumn(ColumnSchema column, boolean isWritable) { this.column = column; dataType = column.getDataType(); this.isWritable = isWritable; } SimpleName getSimpleName() { if (alias != null) { return alias; } if (rangeVariable != null && rangeVariable.hasColumnAlias()) { return rangeVariable.getColumnAlias(columnIndex); } if (column != null) { return column.getName(); } if (opType == OpTypes.COALESCE) { return nodes[LEFT].getSimpleName(); } else if (opType == OpTypes.ROWNUM) { return rownumName; } return null; } String getAlias() { if (alias != null) { return alias.name; } switch (opType) { case OpTypes.COLUMN: case OpTypes.COALESCE: case OpTypes.ROWNUM: return columnName; } return ""; } public String getBaseColumnName() { if (opType == OpTypes.COLUMN && rangeVariable != null) { return rangeVariable.getTable().getColumn(columnIndex).getName().name; } return null; } public HsqlName getBaseColumnHsqlName() { return column.getName(); } void collectObjectNames(Set set) { switch (opType) { case OpTypes.SEQUENCE: HsqlName name = sequence.getName(); set.add(name); return; case OpTypes.MULTICOLUMN: case OpTypes.DYNAMIC_PARAM: case OpTypes.ASTERISK: case OpTypes.SIMPLE_COLUMN: case OpTypes.COALESCE: break; case OpTypes.PARAMETER: case OpTypes.VARIABLE: break; case OpTypes.COLUMN: set.add(column.getName()); if (column.getName().parent != null) { set.add(column.getName().parent); } return; } } String getColumnName() { if (opType == OpTypes.COLUMN && column != null) { return column.getName().name; } return getAlias(); } ColumnSchema getColumn() { return column; } String getSchemaName() { return schema; } RangeVariable getRangeVariable() { return rangeVariable; } public HsqlList resolveColumnReferences( Session session, RangeVariable[] rangeVarArray, int rangeCount, HsqlList unresolvedSet, boolean acceptsSequences) { switch (opType) { case OpTypes.SEQUENCE: if (!acceptsSequences) { throw Error.error(ErrorCode.X_42598); } break; case OpTypes.ROWNUM: case OpTypes.MULTICOLUMN: case OpTypes.DYNAMIC_PARAM: case OpTypes.ASTERISK: case OpTypes.SIMPLE_COLUMN: case OpTypes.COALESCE: case OpTypes.DIAGNOSTICS_VARIABLE: break; case OpTypes.COLUMN: case OpTypes.PARAMETER: case OpTypes.VARIABLE: { boolean resolved = false; boolean tableQualified = tableName != null; if (rangeVariable != null) { return unresolvedSet; } for (int i = 0; i < rangeCount; i++) { RangeVariable rangeVar = rangeVarArray[i]; if (rangeVar == null) { continue; } if (resolved) { if (session.database.sqlEnforceRefs) { if (resolvesDuplicateColumnReference(rangeVar)) { String message = getColumnName(); if (alias != null) { StringBuffer sb = new StringBuffer(message); sb.append(' ').append(Tokens.T_AS).append(' ').append(alias.getStatementName()); message = sb.toString(); } throw Error.error(ErrorCode.X_42580, message); } } } else { if (resolveColumnReference(rangeVar)) { if (tableQualified) { return unresolvedSet; } resolved = true; continue; } } } if (resolved) { return unresolvedSet; } if (session.database.sqlSyntaxOra) { if (acceptsSequences && tableName != null) { if (Tokens.T_CURRVAL.equals(columnName)) { NumberSequence seq = session.database.schemaManager.getSequence( tableName, session.getSchemaName(schema), false); if (seq != null) { opType = OpTypes.SEQUENCE_CURRENT; dataType = seq.getDataType(); sequence = seq; schema = null; tableName = null; columnName = null; resolved = true; } } else if (Tokens.T_NEXTVAL.equals(columnName)) { NumberSequence seq = session.database.schemaManager.getSequence( tableName, session.getSchemaName(schema), false); if (seq != null) { opType = OpTypes.SEQUENCE; dataType = seq.getDataType(); sequence = seq; schema = null; tableName = null; columnName = null; resolved = true; } } } } if (resolved) { return unresolvedSet; } if (unresolvedSet == null) { unresolvedSet = new ArrayListIdentity(); } unresolvedSet.add(this); } } return unresolvedSet; } private boolean resolveColumnReference(RangeVariable rangeVar) { Expression e = rangeVar.getColumnExpression(columnName); if (e != null) { opType = e.opType; nodes = e.nodes; dataType = e.dataType; return true; } int colIndex = rangeVar.findColumn(schema, tableName, columnName); if (colIndex == -1) { return false; } switch (rangeVar.rangeType) { case RangeVariable.PARAMETER_RANGE: case RangeVariable.VARIALBE_RANGE: { if (tableName != null) { return false; } ColumnSchema column = rangeVar.getColumn(colIndex); if (column.getParameterMode() == SchemaObject.ParameterModes.PARAM_OUT) { return false; } else { opType = rangeVar.rangeType == RangeVariable.VARIALBE_RANGE ? OpTypes.VARIABLE : OpTypes.PARAMETER; } break; } case RangeVariable.TRANSITION_RANGE: { if (tableName == null) { return false; } if (schema != null) { return false; } opType = OpTypes.TRANSITION_VARIABLE; break; } default: { break; } } setAttributesAsColumn(rangeVar, colIndex); return true; } boolean resolvesDuplicateColumnReference(RangeVariable rangeVar) { if (tableName == null) { Expression e = rangeVar.getColumnExpression(columnName); if (e != null) { return false; } switch (rangeVar.rangeType) { case RangeVariable.PARAMETER_RANGE: case RangeVariable.VARIALBE_RANGE: case RangeVariable.TRANSITION_RANGE: return false; default: int colIndex = rangeVar.findColumn(schema, tableName, columnName); return colIndex != -1; } } return false; } public void resolveTypes(Session session, Expression parent) { switch (opType) { case OpTypes.DEFAULT: if (parent != null && parent.opType != OpTypes.ROW) { throw Error.error(ErrorCode.X_42544); } break; case OpTypes.COALESCE: { Type type = null; for (int i = 0; i < nodes.length; i++) { type = Type.getAggregateType(nodes[i].dataType, type); } dataType = type; break; } } } public Object getValue(Session session) { switch (opType) { case OpTypes.DEFAULT: return null; case OpTypes.DIAGNOSTICS_VARIABLE: { return getDiagnosticsVariable(session); } case OpTypes.VARIABLE: { return session.sessionContext.routineVariables[columnIndex]; } case OpTypes.PARAMETER: { return session.sessionContext.routineArguments[columnIndex]; } case OpTypes.TRANSITION_VARIABLE: { return session.sessionContext.triggerArguments[rangeVariable.rangePosition][columnIndex]; } case OpTypes.COLUMN: { Object value = session.sessionContext.rangeIterators[rangeVariable.rangePosition].getCurrent( columnIndex); if (dataType != column.dataType) { value = dataType.convertToType(session, value, column.dataType); } return value; } case OpTypes.SIMPLE_COLUMN: { Object value = session.sessionContext.rangeIterators[rangePosition].getCurrent(columnIndex); return value; } case OpTypes.COALESCE: { Object value = null; for (int i = 0; i < nodes.length; i++) { value = nodes[i].getValue(session, dataType); if (value != null) { return value; } } return value; } case OpTypes.DYNAMIC_PARAM: { return session.sessionContext.dynamicArguments[parameterIndex]; } case OpTypes.SEQUENCE: { return session.sessionData.getSequenceValue(sequence); } case OpTypes.SEQUENCE_CURRENT: { return session.sessionData.getSequenceCurrent(sequence); } case OpTypes.ROWNUM: { return ValuePool.getInt(session.sessionContext.rownum); } case OpTypes.ASTERISK: case OpTypes.MULTICOLUMN: default: throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionColumn"); } } private Object getDiagnosticsVariable(Session session) { return session.sessionContext.diagnosticsVariables[columnIndex]; } public String getSQL() { switch (opType) { case OpTypes.DEFAULT: return Tokens.T_DEFAULT; case OpTypes.DYNAMIC_PARAM: return Tokens.T_QUESTION; case OpTypes.ASTERISK: return "*"; case OpTypes.COALESCE: return alias.getStatementName(); case OpTypes.DIAGNOSTICS_VARIABLE: case OpTypes.VARIABLE: case OpTypes.PARAMETER: return column.getName().statementName; case OpTypes.ROWNUM: { StringBuffer sb = new StringBuffer(Tokens.T_ROWNUM); sb.append('(').append(')'); } case OpTypes.COLUMN: { if (column == null) { if (alias != null) { return alias.getStatementName(); } else { return columnName; } } if (rangeVariable.tableAlias == null) { return column.getName().getSchemaQualifiedStatementName(); } else { StringBuffer sb = new StringBuffer(); sb.append(rangeVariable.tableAlias.getStatementName()); sb.append('.'); sb.append(column.getName().statementName); return sb.toString(); } } case OpTypes.MULTICOLUMN: { if (nodes.length == 0) { return "*"; } StringBuffer sb = new StringBuffer(); for (int i = 0; i < nodes.length; i++) { Expression e = nodes[i]; if (i > 0) { sb.append(','); } String s = e.getSQL(); sb.append(s); } return sb.toString(); } default: throw Error.runtimeError(ErrorCode.U_S0500, "ExpressionColumn"); } } protected String describe(Session session, int blanks) { StringBuffer sb = new StringBuffer(64); sb.append('\n'); for (int i = 0; i < blanks; i++) { sb.append(' '); } switch (opType) { case OpTypes.DEFAULT: sb.append(Tokens.T_DEFAULT); break; case OpTypes.ASTERISK: sb.append("OpTypes.ASTERISK "); break; case OpTypes.VARIABLE: sb.append("VARIABLE: "); sb.append(column.getName().name); break; case OpTypes.PARAMETER: sb.append(Tokens.T_PARAMETER).append(": "); sb.append(column.getName().name); break; case OpTypes.COALESCE: sb.append(Tokens.T_COLUMN).append(": "); sb.append(columnName); if (alias != null) { sb.append(" AS ").append(alias.name); } break; case OpTypes.COLUMN: sb.append(Tokens.T_COLUMN).append(": "); sb.append(column.getName().getSchemaQualifiedStatementName()); if (alias != null) { sb.append(" AS ").append(alias.name); } break; case OpTypes.DYNAMIC_PARAM: sb.append("DYNAMIC PARAM: "); sb.append(", TYPE = ").append(dataType.getNameString()); break; case OpTypes.SEQUENCE: sb.append(Tokens.T_SEQUENCE).append(": "); sb.append(sequence.getName().name); break; case OpTypes.MULTICOLUMN: // shouldn't get here } return sb.toString(); } /** * Returns the table name used in query * * @return table name */ String getTableName() { if (opType == OpTypes.MULTICOLUMN) { return tableName; } if (opType == OpTypes.COLUMN) { if (rangeVariable == null) { return tableName; } else { return rangeVariable.getTable().getName().name; } } return ""; } static void checkColumnsResolved(HsqlList set) { if (set != null && !set.isEmpty()) { StringBuffer sb = new StringBuffer(); Expression e = (Expression) set.get(0); if (e instanceof ExpressionColumn) { ExpressionColumn c = (ExpressionColumn) e; if (c.schema != null) { sb.append(c.schema + '.'); } if (c.tableName != null) { sb.append(c.tableName + '.'); } throw Error.error(ErrorCode.X_42501, sb.toString() + c.getColumnName()); } else { OrderedHashSet newSet = new OrderedHashSet(); e.collectAllExpressions( newSet, Expression.columnExpressionSet, Expression.emptyExpressionSet); // throw with column name checkColumnsResolved(newSet); // throw anyway if not found throw Error.error(ErrorCode.X_42501); } } } public OrderedHashSet getUnkeyedColumns(OrderedHashSet unresolvedSet) { for (int i = 0; i < nodes.length; i++) { if (nodes[i] == null) { continue; } unresolvedSet = nodes[i].getUnkeyedColumns(unresolvedSet); } if (opType == OpTypes.COLUMN && !rangeVariable.hasKeyedColumnInGroupBy) { if (unresolvedSet == null) { unresolvedSet = new OrderedHashSet(); } unresolvedSet.add(this); } return unresolvedSet; } /** collects all range variables in expression tree */ void collectRangeVariables(RangeVariable[] rangeVariables, Set set) { for (int i = 0; i < nodes.length; i++) { if (nodes[i] != null) { nodes[i].collectRangeVariables(rangeVariables, set); } } if (rangeVariable != null) { for (int i = 0; i < rangeVariables.length; i++) { if (rangeVariables[i] == rangeVariable) { set.add(rangeVariable); break; } } } } Expression replaceAliasInOrderBy(Expression[] columns, int length) { for (int i = 0; i < nodes.length; i++) { if (nodes[i] == null) { continue; } nodes[i] = nodes[i].replaceAliasInOrderBy(columns, length); } switch (opType) { case OpTypes.COALESCE: case OpTypes.COLUMN: { for (int i = 0; i < length; i++) { SimpleName aliasName = columns[i].alias; String alias = aliasName == null ? null : aliasName.name; if (schema == null && tableName == null && columnName.equals(alias)) { return columns[i]; } } for (int i = 0; i < length; i++) { if (columns[i] instanceof ExpressionColumn) { if (this.equals(columns[i])) { return columns[i]; } if (tableName == null && schema == null && columnName.equals(((ExpressionColumn) columns[i]).columnName)) { return columns[i]; } } } } default: } return this; } Expression replaceColumnReferences(RangeVariable range, Expression[] list) { if (opType == OpTypes.COLUMN && rangeVariable == range) { return list[columnIndex]; } for (int i = 0; i < nodes.length; i++) { if (nodes[i] == null) { continue; } nodes[i] = nodes[i].replaceColumnReferences(range, list); } return this; } /** return true if given RangeVariable is used in expression tree */ boolean hasReference(RangeVariable range) { if (range == rangeVariable) { return true; } for (int i = 0; i < nodes.length; i++) { if (nodes[i] != null) { if (nodes[i].hasReference(range)) { return true; } } } return false; } /** SIMPLE_COLUMN expressions can be of different Java types */ public boolean equals(Expression other) { if (other == this) { return true; } if (other == null) { return false; } if (opType != other.opType) { return false; } switch (opType) { case OpTypes.SIMPLE_COLUMN: return this.columnIndex == other.columnIndex; case OpTypes.COALESCE: return nodes == other.nodes; case OpTypes.VARIABLE: case OpTypes.PARAMETER: case OpTypes.COLUMN: return column == other.getColumn() && rangeVariable == other.getRangeVariable(); default: return false; } } void replaceRangeVariables(RangeVariable[] ranges, RangeVariable[] newRanges) { for (int i = 0; i < nodes.length; i++) { nodes[i].replaceRangeVariables(ranges, newRanges); } for (int i = 0; i < ranges.length; i++) { if (rangeVariable == ranges[i]) { rangeVariable = newRanges[i]; break; } } } void resetColumnReferences() { rangeVariable = null; columnIndex = -1; } public boolean isIndexable(RangeVariable range) { if (opType == OpTypes.COLUMN) { return rangeVariable == range; } return false; } public boolean isUnresolvedParam() { return isParam && dataType == null; } boolean isDynamicParam() { return isParam; } RangeVariable[] getJoinRangeVariables(RangeVariable[] ranges) { if (opType == OpTypes.COLUMN) { return new RangeVariable[] {rangeVariable}; } return RangeVariable.emptyArray; } /** For normal tables only. We don't want to create an index on each column that is checked. */ double costFactor(Session session, RangeVariable range, int operation) { PersistentStore store = range.rangeTable.getRowStore(session); int indexType = range.rangeTable.indexTypeForColumn(session, columnIndex); double factor; switch (indexType) { case Index.INDEX_UNIQUE: if (operation == OpTypes.EQUAL) { factor = 1; } else { factor = store.elementCount() / 2; } break; case Index.INDEX_NON_UNIQUE: if (operation == OpTypes.EQUAL) { factor = store.elementCount() / 8; if (factor > 1024) { factor = 1024; } } else { factor = store.elementCount() / 2; } break; case Index.INDEX_NONE: default: factor = store.elementCount(); break; } return factor < Index.minimumSelectivity ? Index.minimumSelectivity : factor; } }
static { staticManager.serialNumber = Integer.MIN_VALUE; }