use of org.apache.derby.catalog.DefaultInfo in project derby by apache.
the class GeneratedColumnsTest method getColumnDefault.
/**
* <p>
* Returns the column default for a column.
* </p>
*/
public DefaultInfo getColumnDefault(Connection conn, String tableName, String columnName) throws SQLException {
PreparedStatement ps = chattyPrepare(conn, "select c.columndefault\n" + "from sys.syscolumns c, sys.systables t\n" + "where t.tableid = c.referenceid\n" + "and t.tablename = ?\n" + "and c.columnname = ?");
ps.setString(1, tableName);
ps.setString(2, columnName);
ResultSet rs = ps.executeQuery();
rs.next();
DefaultInfo result = (DefaultInfo) rs.getObject(1);
rs.close();
ps.close();
return result;
}
use of org.apache.derby.catalog.DefaultInfo in project derby by apache.
the class GeneratedColumnsTest method assertDefaultInfo.
/**
* <p>
* Assert that a column has the expected generation clause.
* </p>
*/
private void assertDefaultInfo(Connection conn, String tableName, String columnName, String[] expectedReferenceColumns, String expectedDefaultText) throws Exception {
DefaultInfo di = getColumnDefault(conn, tableName, columnName);
String[] actualReferenceColumns = di.getReferencedColumnNames();
assertEquals(fill(expectedReferenceColumns).toString(), fill(actualReferenceColumns).toString());
assertEquals(expectedDefaultText, di.getDefaultText());
assertTrue(di.isGeneratedColumn());
}
use of org.apache.derby.catalog.DefaultInfo in project derby by apache.
the class UpdateNode method addGeneratedColumns.
/**
* Add generated columns to the update list as necessary. We add
* any column whose generation clause mentions columns already
* in the update list. We fill in a list of all generated columns affected
* by this update. We also fill in a list of all generated columns which we
* added to the update list.
*/
private void addGeneratedColumns(TableDescriptor baseTable, ResultSetNode updateSet, ColumnDescriptorList affectedGeneratedColumns, ColumnDescriptorList addedGeneratedColumns) throws StandardException {
ResultColumnList updateColumnList = updateSet.getResultColumns();
ColumnDescriptorList generatedColumns = baseTable.getGeneratedColumns();
HashSet<String> updatedColumns = new HashSet<String>();
UUID tableID = baseTable.getObjectID();
for (ResultColumn rc : updateColumnList) {
updatedColumns.add(rc.getName());
}
for (ColumnDescriptor gc : generatedColumns) {
DefaultInfo defaultInfo = gc.getDefaultInfo();
String[] mentionedColumnNames = defaultInfo.getReferencedColumnNames();
int mentionedColumnCount = mentionedColumnNames.length;
// literal
if (updatedColumns.contains(gc.getColumnName())) {
affectedGeneratedColumns.add(tableID, gc);
}
// update
for (String mcn : mentionedColumnNames) {
if (updatedColumns.contains(mcn)) {
// Yes, we are updating one of the columns mentioned in
// this generation clause.
affectedGeneratedColumns.add(tableID, gc);
// add it.
if (!updatedColumns.contains(gc.getColumnName())) {
addedGeneratedColumns.add(tableID, gc);
// we will fill in the real value later on in parseAndBindGenerationClauses();
ValueNode dummy = new UntypedNullConstantNode(getContextManager());
ResultColumn newResultColumn = new ResultColumn(gc.getType(), dummy, getContextManager());
newResultColumn.setColumnDescriptor(baseTable, gc);
newResultColumn.setName(gc.getColumnName());
updateColumnList.addResultColumn(newResultColumn);
}
break;
}
}
// done looping through mentioned columns
}
// done looping through generated columns
}
use of org.apache.derby.catalog.DefaultInfo in project derby by apache.
the class DMLModStatementNode method parseAndBindGenerationClauses.
/**
* Parse and bind the generating expressions of computed columns.
*
* @param dataDictionary metadata
* @param targetTableDescriptor metadata for the table that has the generated columns
* @param sourceRCL the tuple stream which drives the INSERT or UPDATE
* @param targetRCL the row in the table that's being INSERTed or UPDATEd
* @param forUpdate true if this is an UPDATE. false otherwise.
* @param updateResultSet more information on the tuple stream driving the UPDATE
*/
void parseAndBindGenerationClauses(DataDictionary dataDictionary, TableDescriptor targetTableDescriptor, ResultColumnList sourceRCL, ResultColumnList targetRCL, boolean forUpdate, ResultSetNode updateResultSet) throws StandardException {
CompilerContext compilerContext = getCompilerContext();
int count = targetRCL.size();
for (int i = 0; i < count; i++) {
ResultColumn rc = targetRCL.elementAt(i);
//
if (forUpdate && !rc.updated()) {
continue;
}
if (rc.hasGenerationClause()) {
ColumnDescriptor colDesc = rc.getTableColumnDescriptor();
DataTypeDescriptor dtd = colDesc.getType();
DefaultInfo di = colDesc.getDefaultInfo();
ValueNode generationClause = parseGenerationClause(di.getDefaultText(), targetTableDescriptor);
// insert CAST in case column data type is not same as the
// resolved type of the generation clause
generationClause = new CastNode(generationClause, dtd, getContextManager());
// Assignment semantics of implicit cast here:
// Section 9.2 (Store assignment). There, General Rule
// 2.b.v.2 says that the database should raise an exception
// if truncation occurs when stuffing a string value into a
// VARCHAR, so make sure CAST doesn't issue warning only.
((CastNode) generationClause).setAssignmentSemantics();
//
// Unqualified function references should resolve to the
// current schema at the time that the table was
// created/altered. See DERBY-3945.
//
compilerContext.pushCompilationSchema(getSchemaDescriptor(di.getOriginalCurrentSchema(), false));
try {
bindRowScopedExpression(getOptimizerFactory(), getContextManager(), targetTableDescriptor, sourceRCL, generationClause);
} finally {
compilerContext.popCompilationSchema();
}
ResultColumn newRC = new ResultColumn(generationClause.getTypeServices(), generationClause, getContextManager());
// replace the result column in place
// column ids are 1-based
newRC.setVirtualColumnId(i + 1);
newRC.setColumnDescriptor(targetTableDescriptor, colDesc);
targetRCL.setElementAt(newRC, i);
// generate correctly if they reference the generated column
if (forUpdate) {
for (int j = 0; j < sourceRCL.size(); j++) {
if (rc == sourceRCL.elementAt(j)) {
newRC.setName(rc.getName());
newRC.setResultSetNumber(updateResultSet.getResultSetNumber());
sourceRCL.setElementAt(newRC, j);
}
}
// end of loop through sourceRCL
}
// end if this is an update statement
}
// end if this is a generated column
}
// end of loop through targetRCL
}
Aggregations