📄 resultcolumn.java
字号:
{ ResultColumn newResultColumn; ValueNode cloneExpr; /* If expression is a ColumnReference, then we want to * have the RC's clone have a clone of the ColumnReference * for it's expression. This is for the special case of * cloning the SELECT list for the HAVING clause in the parser. * The SELECT generated for the HAVING needs its own copy * of the ColumnReferences. */ if (expression instanceof ColumnReference) { cloneExpr = ((ColumnReference) expression).getClone(); } else { cloneExpr = expression; } /* If a columnDescriptor exists, then we must propagate it */ if (columnDescriptor != null) { newResultColumn = (ResultColumn) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN, columnDescriptor, expression, getContextManager()); newResultColumn.setExpression(cloneExpr); } else { newResultColumn = (ResultColumn) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN, getName(), cloneExpr, getContextManager()); } /* Set the VirtualColumnId and name in the new node */ newResultColumn.setVirtualColumnId(getVirtualColumnId()); /* Set the type and name information in the new node */ newResultColumn.setName(getName()); newResultColumn.setType(getTypeServices()); newResultColumn.setNameGenerated(isNameGenerated()); /* Set the "is generated for unmatched column in insert" status in the new node This if for bug 4194*/ if (isGeneratedForUnmatchedColumnInInsert()) newResultColumn.markGeneratedForUnmatchedColumnInInsert(); /* Set the "is referenced" status in the new node */ if (isReferenced()) newResultColumn.setReferenced(); /* Set the "updated" status in the new node */ if (updated()) newResultColumn.markUpdated(); /* Setthe "updatable by cursor" status in the new node */ if (updatableByCursor()) newResultColumn.markUpdatableByCursor(); if (isAutoincrementGenerated()) newResultColumn.setAutoincrementGenerated(); if (isAutoincrement()) newResultColumn.setAutoincrement(); return newResultColumn; } /** * Get the maximum size of the column * * @return the max size */ public int getMaximumColumnSize() { return dataTypeServices.getTypeId() .getApproximateLengthInBytes(dataTypeServices); } /** * Return the variant type for the underlying expression. * The variant type can be: * VARIANT - variant within a scan * (method calls and non-static field access) * SCAN_INVARIANT - invariant within a scan * (column references from outer tables) * QUERY_INVARIANT - invariant within the life of a query * CONSTANT - constant * * @return The variant type for the underlying expression. * @exception StandardException thrown on error */ protected int getOrderableVariantType() throws StandardException { /* ** If the expression is VARIANT, then ** return VARIANT. Otherwise, we return ** CONSTANT. For result columns that are ** generating autoincrement values, the result ** is variant-- note that there is no expression ** associated with an autoincrement column in ** an insert statement. */ int expType = ((expression != null) ? expression.getOrderableVariantType() : ((isAutoincrementGenerated()) ? Qualifier.VARIANT : Qualifier.CONSTANT)); switch (expType) { case Qualifier.VARIANT: return Qualifier.VARIANT; case Qualifier.SCAN_INVARIANT: case Qualifier.QUERY_INVARIANT: return Qualifier.SCAN_INVARIANT; default: return Qualifier.CONSTANT; } } /** * Accept a visitor, and call v.visit() * on child nodes as necessary. * * @param v the visitor * * @exception StandardException on error */ public Visitable accept(Visitor v) throws StandardException { Visitable returnNode = v.visit(this); if (v.skipChildren(this)) { return returnNode; } if (expression != null && !v.stopTraversal()) { expression = (ValueNode)expression.accept(v); } return returnNode; } /** * Set the nullability of this ResultColumn. */ public void setNullability(boolean nullability) { dataTypeServices.setNullability(nullability); } /** * Is this column in this array of strings? * * @param list the array of column names to compare * * @return true/false */ public boolean foundInList(String[] list) { return foundString(list, name); } /** * Verify that this RC is orderable. * * @return Nothing. * * @exception StandardException Thrown on error */ void verifyOrderable() throws StandardException { /* * Do not check to see if we can map user types * to built-in types. The ability to do so does * not mean that ordering will work. In fact, * as of version 2.0, ordering does not work on * user types. */ if (!getTypeId().orderable(getClassFactory())) { throw StandardException.newException(SQLState.LANG_COLUMN_NOT_ORDERABLE_DURING_EXECUTION, getTypeId().getSQLTypeName()); } } /** If this ResultColumn is bound to a column in a table get the column descriptor for the column in the table. Otherwise return null. */ ColumnDescriptor getTableColumnDescriptor() {return columnDescriptor;} /** * Returns true if this result column is a placeholder for a generated * autoincrement value. */ public boolean isAutoincrementGenerated() { return autoincrementGenerated; } public void setAutoincrementGenerated() { autoincrementGenerated = true; } public void resetAutoincrementGenerated() { autoincrementGenerated = false; } public boolean isAutoincrement() { return autoincrement; } public void setAutoincrement() { autoincrement = true; } /** * @exception StandardException Thrown on error */ private DataValueDescriptor convertConstant(TypeId toTypeId, int maxWidth, DataValueDescriptor constantValue) throws StandardException { int formatId = toTypeId.getTypeFormatId(); DataValueFactory dvf = getDataValueFactory(); switch (formatId) { default: case StoredFormatIds.CHAR_TYPE_ID: return constantValue; case StoredFormatIds.VARCHAR_TYPE_ID: case StoredFormatIds.NATIONAL_CHAR_TYPE_ID: case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID: String sourceValue = constantValue.getString(); int sourceWidth = sourceValue.length(); int posn; /* ** If the input is already the right length, no normalization is ** necessary - just return the source. ** */ if (sourceWidth <= maxWidth) { switch (formatId) { // For NCHAR we must pad the result, saves on normilization later if all // constants are of the correct size case StoredFormatIds.NATIONAL_CHAR_TYPE_ID: if (sourceWidth < maxWidth) { StringBuffer stringBuffer = new StringBuffer(sourceValue); int needed = maxWidth - sourceWidth; char blankArray[] = new char[needed]; for (int i = 0; i < needed; i++) blankArray[i] = ' '; stringBuffer.append(blankArray, 0, maxWidth - sourceWidth); sourceValue = stringBuffer.toString(); } return dvf.getNationalCharDataValue(sourceValue); case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID: return dvf.getNationalVarcharDataValue(sourceValue); case StoredFormatIds.VARCHAR_TYPE_ID: return dvf.getVarcharDataValue(sourceValue); } } /* ** Check whether any non-blank characters will be truncated. */ for (posn = maxWidth; posn < sourceWidth; posn++) { if (sourceValue.charAt(posn) != ' ') { String typeName = null; switch (formatId) { case StoredFormatIds.NATIONAL_CHAR_TYPE_ID: typeName = TypeId.NATIONAL_CHAR_NAME; break; case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID: typeName = TypeId.NATIONAL_VARCHAR_NAME; break; case StoredFormatIds.VARCHAR_TYPE_ID: typeName = TypeId.VARCHAR_NAME; break; } throw StandardException.newException(SQLState.LANG_STRING_TRUNCATION, typeName, StringUtil.formatForPrint(sourceValue), String.valueOf(maxWidth)); } } switch (formatId) { case StoredFormatIds.NATIONAL_CHAR_TYPE_ID: return dvf.getNationalCharDataValue(sourceValue.substring(0, maxWidth)); case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID: return dvf.getNationalVarcharDataValue(sourceValue.substring(0, maxWidth)); case StoredFormatIds.VARCHAR_TYPE_ID: return dvf.getVarcharDataValue(sourceValue.substring(0, maxWidth)); } case StoredFormatIds.LONGVARCHAR_TYPE_ID: //No need to check widths here (unlike varchar), since no max width return dvf.getLongvarcharDataValue(constantValue.getString()); case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID: //No need to check widths here (unlike varchar), since no max width return dvf.getNationalLongvarcharDataValue(constantValue.getString()); } } /** * Get the TypeId from this Node. * * @return The TypeId from this Node. This * may be null if the node isn't bound yet. */ public TypeId getTypeId() { TypeId t = super.getTypeId(); if( t == null) { if( expression != null) { DataTypeDescriptor dtd = getTypeServices(); if( dtd != null) t = dtd.getTypeId(); } } return t; } // end of getTypeId /** * Get the DataTypeServices from this Node. * * @return The DataTypeServices from this Node. This * may be null if the node isn't bound yet. */ public DataTypeDescriptor getTypeServices() { DataTypeDescriptor dtd = super.getTypeServices(); if( dtd == null && expression != null) { dtd = expression.getTypeServices(); if( dtd != null) setType( dtd); } return dtd; } // end of getTypeServices public TableName getTableNameObject() { return null; } /** * Get the source BaseColumnNode for this result column. The * BaseColumnNode cannot be found unless the ResultColumn is bound * and is a simple reference to a column in a BaseFromTable. * * @return a BaseColumnNode, * or null if a BaseColumnNode cannot be found */ public BaseColumnNode getBaseColumnNode() { ValueNode vn = expression; while (true) { if (vn instanceof ResultColumn) { vn = ((ResultColumn) vn).expression; } else if (vn instanceof ColumnReference) { vn = ((ColumnReference) vn).getSource(); } else if (vn instanceof VirtualColumnNode) { vn = ((VirtualColumnNode) vn).getSourceColumn(); } else if (vn instanceof BaseColumnNode) { return (BaseColumnNode) vn; } else { return null; } } } /** * Search the tree beneath this ResultColumn until we find * the number of the table to which this RC points, and * return that table number. If we can't determine which * table this RC is for, then return -1. * * There are two places we can find the table number: 1) if * our expression is a ColumnReference, then we can get the * target table number from the ColumnReference and that's * it; 2) if expression is a VirtualColumnNode, then if * the VirtualColumnNode points to a FromBaseTable, we can * get that FBT's table number; otherwise, we walk the * VirtualColumnNode-ResultColumn chain and do a recursive * search. * * @return The number of the table to which this ResultColumn * points, or -1 if we can't determine that from where we are. */ public int getTableNumber() throws StandardException { if (expression instanceof ColumnReference) return ((ColumnReference)expression).getTableNumber(); else if (expression instanceof VirtualColumnNode) { VirtualColumnNode vcn = (VirtualColumnNode)expression; // If the VCN points to a FromBaseTable, just get that // table's number. if (vcn.getSourceResultSet() instanceof FromBaseTable) { return ((FromBaseTable)vcn.getSourceResultSet()). getTableNumber(); } // Else recurse down the VCN. return vcn.getSourceColumn().getTableNumber(); } // We can get here if expression has neither a column // reference nor a FromBaseTable beneath it--for example, // if it is of type BaseColumnNode. return -1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -