/** * Format result set. * * @param rs the rs * @return the string */ private String formatResultSet(LensClient.LensClientResultSetWithStats rs) { StringBuilder b = new StringBuilder(); if (rs.getResultSet() != null) { QueryResultSetMetadata resultSetMetadata = rs.getResultSet().getResultSetMetadata(); for (ResultColumn column : resultSetMetadata.getColumns()) { b.append(column.getName()).append("\t"); } b.append("\n"); QueryResult r = rs.getResultSet().getResult(); if (r instanceof InMemoryQueryResult) { InMemoryQueryResult temp = (InMemoryQueryResult) r; b.append(temp.toPrettyString()); } else { PersistentQueryResult temp = (PersistentQueryResult) r; b.append("Results of query stored at : ").append(temp.getPersistedURI()).append(" "); if (null != temp.getNumRows()) { b.append(temp.getNumRows()).append(" rows "); } } } if (rs.getQuery() != null) { long submissionTime = rs.getQuery().getSubmissionTime(); long endTime = rs.getQuery().getFinishTime(); b.append("processed in (") .append(endTime > 0 ? ((endTime - submissionTime) / 1000) : 0) .append(") seconds.\n"); } return b.toString(); }
/** * Try to find a ResultColumn in the table represented by this FromBaseTable that matches the name * in the given ColumnReference. * * @param columnReference The columnReference whose name we're looking for in the given table. * @return A ResultColumn whose expression is the ColumnNode that matches the ColumnReference. * Returns null if there is no match. * @exception StandardException Thrown on error */ public ResultColumn getMatchingColumn(ColumnReference columnReference) throws StandardException { ResultColumn resultColumn = null; String columnsTableName; /* ** RESOLVE: When we add support for schemas, check to see if ** the column name specifies a schema, and if so, if this ** table is in that schema. */ columnsTableName = columnReference.getTableName(); // post 681, 1 may be no longer needed. 5 is the default case // now but what happens if the condition is false? Investigate. if (columnReference.getGeneratedToReplaceAggregate()) // 1 { resultColumn = resultColumns.getResultColumn(columnReference.getColumnName()); } else if (columnsTableName == null || columnsTableName.equals(correlationName)) // 5? { resultColumn = resultColumns.getAtMostOneResultColumn(columnReference, correlationName, false); } if (resultColumn != null) { columnReference.setTableNumber(tableNumber); columnReference.setColumnNumber(resultColumn.getColumnPosition()); } return resultColumn; }
/** * Bind this CreateTableNode. This means doing any static error checking that can be done before * actually creating the base table or declaring the global temporary table. For eg, verifying * that the TableElementList does not contain any duplicate column names. * * @exception StandardException Thrown on error */ public void bindStatement() throws StandardException { DataDictionary dataDictionary = getDataDictionary(); int numPrimaryKeys = 0; int numCheckConstraints = 0; int numReferenceConstraints = 0; int numUniqueConstraints = 0; int numGenerationClauses = 0; SchemaDescriptor sd = getSchemaDescriptor(tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE, true); if (queryExpression != null) { FromList fromList = (FromList) getNodeFactory() .getNode( C_NodeTypes.FROM_LIST, getNodeFactory().doJoinOrderOptimization(), getContextManager()); CompilerContext cc = getCompilerContext(); ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList(); ProviderList apl = new ProviderList(); try { cc.setCurrentAuxiliaryProviderList(apl); cc.pushCurrentPrivType(Authorizer.SELECT_PRIV); /* Bind the tables in the queryExpression */ queryExpression = queryExpression.bindNonVTITables(dataDictionary, fromList); queryExpression = queryExpression.bindVTITables(fromList); /* Bind the expressions under the resultSet */ queryExpression.bindExpressions(fromList); /* Bind the query expression */ queryExpression.bindResultColumns(fromList); /* Reject any untyped nulls in the RCL */ /* e.g. CREATE TABLE t1 (x) AS VALUES NULL WITH NO DATA */ queryExpression.bindUntypedNullsToResultColumns(null); } finally { cc.popCurrentPrivType(); cc.setCurrentAuxiliaryProviderList(prevAPL); } /* If there is an RCL for the table definition then copy the * names to the queryExpression's RCL after verifying that * they both have the same size. */ ResultColumnList qeRCL = queryExpression.getResultColumns(); if (resultColumns != null) { if (resultColumns.size() != qeRCL.visibleSize()) { throw StandardException.newException( SQLState.LANG_TABLE_DEFINITION_R_C_L_MISMATCH, getFullName()); } qeRCL.copyResultColumnNames(resultColumns); } int schemaCollationType = sd.getCollationType(); /* Create table element list from columns in query expression */ tableElementList = new TableElementList(); for (int index = 0; index < qeRCL.size(); index++) { ResultColumn rc = (ResultColumn) qeRCL.elementAt(index); if (rc.isGenerated()) { continue; } /* Raise error if column name is system generated. */ if (rc.isNameGenerated()) { throw StandardException.newException(SQLState.LANG_TABLE_REQUIRES_COLUMN_NAMES); } DataTypeDescriptor dtd = rc.getExpression().getTypeServices(); if ((dtd != null) && !dtd.isUserCreatableType()) { throw StandardException.newException( SQLState.LANG_INVALID_COLUMN_TYPE_CREATE_TABLE, dtd.getFullSQLTypeName(), rc.getName()); } // DERBY-2879 CREATE TABLE AS <subquery> does not maintain the // collation for character types. // eg for a territory based collation database // create table t as select tablename from sys.systables with no data; // Derby at this point does not support for a table's character // columns to have a collation different from it's schema's // collation. Which means that in a territory based database, // the query above will cause table t's character columns to // have collation of UCS_BASIC but the containing schema of t // has collation of territory based. This is not supported and // hence we will throw an exception below for the query above in // a territory based database. if (dtd.getTypeId().isStringTypeId() && dtd.getCollationType() != schemaCollationType) { throw StandardException.newException( SQLState.LANG_CAN_NOT_CREATE_TABLE, dtd.getCollationName(), DataTypeDescriptor.getCollationName(schemaCollationType)); } ColumnDefinitionNode column = (ColumnDefinitionNode) getNodeFactory() .getNode( C_NodeTypes.COLUMN_DEFINITION_NODE, rc.getName(), null, rc.getType(), null, getContextManager()); tableElementList.addTableElement(column); } } else { // Set the collation type and collation derivation of all the // character type columns. Their collation type will be same as the // collation of the schema they belong to. Their collation // derivation will be "implicit". // Earlier we did this in makeConstantAction but that is little too // late (DERBY-2955) // eg // CREATE TABLE STAFF9 (EMPNAME CHAR(20), // CONSTRAINT STAFF9_EMPNAME CHECK (EMPNAME NOT LIKE 'T%')) // For the query above, when run in a territory based db, we need // to have the correct collation set in bind phase of create table // so that when LIKE is handled in LikeEscapeOperatorNode, we have // the correct collation set for EMPNAME otherwise it will throw an // exception for 'T%' having collation of territory based and // EMPNAME having the default collation of UCS_BASIC tableElementList.setCollationTypesOnCharacterStringColumns( getSchemaDescriptor(tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE, true)); } tableElementList.validate(this, dataDictionary, (TableDescriptor) null); /* Only 1012 columns allowed per table */ if (tableElementList.countNumberOfColumns() > Limits.DB2_MAX_COLUMNS_IN_TABLE) { throw StandardException.newException( SQLState.LANG_TOO_MANY_COLUMNS_IN_TABLE_OR_VIEW, String.valueOf(tableElementList.countNumberOfColumns()), getRelativeName(), String.valueOf(Limits.DB2_MAX_COLUMNS_IN_TABLE)); } numPrimaryKeys = tableElementList.countConstraints(DataDictionary.PRIMARYKEY_CONSTRAINT); /* Only 1 primary key allowed per table */ if (numPrimaryKeys > 1) { throw StandardException.newException( SQLState.LANG_TOO_MANY_PRIMARY_KEY_CONSTRAINTS, getRelativeName()); } /* Check the validity of all check constraints */ numCheckConstraints = tableElementList.countConstraints(DataDictionary.CHECK_CONSTRAINT); numReferenceConstraints = tableElementList.countConstraints(DataDictionary.FOREIGNKEY_CONSTRAINT); numUniqueConstraints = tableElementList.countConstraints(DataDictionary.UNIQUE_CONSTRAINT); numGenerationClauses = tableElementList.countGenerationClauses(); // temp tables can't have primary key or check or foreign key or unique constraints defined on // them if ((tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) && (numPrimaryKeys > 0 || numCheckConstraints > 0 || numReferenceConstraints > 0 || numUniqueConstraints > 0)) throw StandardException.newException( SQLState.LANG_NOT_ALLOWED_FOR_DECLARED_GLOBAL_TEMP_TABLE); // each of these constraints have a backing index in the back. We need to make sure that a table // never has more // more than 32767 indexes on it and that is why this check. if ((numPrimaryKeys + numReferenceConstraints + numUniqueConstraints) > Limits.DB2_MAX_INDEXES_ON_TABLE) { throw StandardException.newException( SQLState.LANG_TOO_MANY_INDEXES_ON_TABLE, String.valueOf(numPrimaryKeys + numReferenceConstraints + numUniqueConstraints), getRelativeName(), String.valueOf(Limits.DB2_MAX_INDEXES_ON_TABLE)); } if ((numCheckConstraints > 0) || (numGenerationClauses > 0) || (numReferenceConstraints > 0)) { /* In order to check the validity of the check constraints and * generation clauses * we must goober up a FromList containing a single table, * the table being created, with an RCL containing the * new columns and their types. This will allow us to * bind the constraint definition trees against that * FromList. When doing this, we verify that there are * no nodes which can return non-deterministic results. */ FromList fromList = makeFromList(null, tableElementList, true); FormatableBitSet generatedColumns = new FormatableBitSet(); /* Now that we've finally goobered stuff up, bind and validate * the check constraints and generation clauses. */ if (numGenerationClauses > 0) { tableElementList.bindAndValidateGenerationClauses(sd, fromList, generatedColumns, null); } if (numCheckConstraints > 0) { tableElementList.bindAndValidateCheckConstraints(fromList); } if (numReferenceConstraints > 0) { tableElementList.validateForeignKeysOnGenerationClauses(fromList, generatedColumns); } } if (numPrimaryKeys > 0) { tableElementList.validatePrimaryKeyNullability(); } }
/** * Expand a "*" into a ResultColumnList with all of the result columns from the subquery. * * @exception StandardException Thrown on error */ public ResultColumnList getAllResultColumns(TableName allTableName) throws StandardException { ResultColumnList rcList = null; TableName exposedName; TableName toCompare; if (allTableName != null) toCompare = makeTableName(allTableName.getSchemaName(), correlationName); else toCompare = makeTableName(null, correlationName); if (allTableName != null && !allTableName.equals(toCompare)) { return null; } /* Cache exposed name for this table. * The exposed name becomes the qualifier for each column * in the expanded list. */ exposedName = makeTableName(null, correlationName); rcList = (ResultColumnList) getNodeFactory().getNode(C_NodeTypes.RESULT_COLUMN_LIST, getContextManager()); /* Build a new result column list based off of resultColumns. * NOTE: This method will capture any column renaming due to * a derived column list. */ // Use visibleSize, because we don't want to propagate any order by // columns not selected. int rclSize = resultColumns.visibleSize(); for (int index = 0; index < rclSize; index++) { ResultColumn resultColumn = (ResultColumn) resultColumns.elementAt(index); ValueNode valueNode; String columnName; if (resultColumn.isGenerated()) { continue; } // Build a ResultColumn/ColumnReference pair for the column // columnName = resultColumn.getName(); boolean isNameGenerated = resultColumn.isNameGenerated(); /* If this node was generated for a GROUP BY, then tablename for the CR, if any, * comes from the source RC. */ TableName tableName; tableName = exposedName; valueNode = (ValueNode) getNodeFactory() .getNode( C_NodeTypes.COLUMN_REFERENCE, columnName, tableName, getContextManager()); resultColumn = (ResultColumn) getNodeFactory() .getNode(C_NodeTypes.RESULT_COLUMN, columnName, valueNode, getContextManager()); resultColumn.setNameGenerated(isNameGenerated); // Build the ResultColumnList to return // rcList.addResultColumn(resultColumn); } return rcList; }