/* * create_ctas_nodata * * Create CTAS or materialized view when WITH NO DATA is used, starting from * the targetlist of the SELECT or view definition. */ static ObjectAddress create_ctas_nodata(List *tlist, IntoClause *into) { List *attrList; ListCell *t, *lc; /* * Build list of ColumnDefs from non-junk elements of the tlist. If a * column name list was specified in CREATE TABLE AS, override the column * names in the query. (Too few column names are OK, too many are not.) */ attrList = NIL; lc = list_head(into->colNames); foreach(t, tlist) { TargetEntry *tle = (TargetEntry *) lfirst(t); if (!tle->resjunk) { ColumnDef *col; char *colname; if (lc) { colname = strVal(lfirst(lc)); lc = lnext(lc); } else colname = tle->resname; col = makeColumnDef(colname, exprType((Node *) tle->expr), exprTypmod((Node *) tle->expr), exprCollation((Node *) tle->expr)); /* * It's possible that the column is of a collatable type but the * collation could not be resolved, so double-check. (We must * check this here because DefineRelation would adopt the type's * default collation rather than complaining.) */ if (!OidIsValid(col->collOid) && type_is_collatable(col->typeName->typeOid)) ereport(ERROR, (errcode(ERRCODE_INDETERMINATE_COLLATION), errmsg("no collation was derived for column \"%s\" with collatable type %s", col->colname, format_type_be(col->typeName->typeOid)), errhint("Use the COLLATE clause to set the collation explicitly."))); attrList = lappend(attrList, col); } }
/*--------------------------------------------------------------------- * DefineVirtualRelation * * Create the "view" relation. `DefineRelation' does all the work, * we just provide the correct arguments ... at least when we're * creating a view. If we're updating an existing view, we have to * work harder. *--------------------------------------------------------------------- */ static ObjectAddress DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, List *options) { Oid viewOid; LOCKMODE lockmode; CreateStmt *createStmt = makeNode(CreateStmt); List *attrList; ListCell *t; /* * create a list of ColumnDef nodes based on the names and types of the * (non-junk) targetlist items from the view's SELECT list. */ attrList = NIL; foreach(t, tlist) { TargetEntry *tle = (TargetEntry *) lfirst(t); if (!tle->resjunk) { ColumnDef *def = makeColumnDef(tle->resname, exprType((Node *) tle->expr), exprTypmod((Node *) tle->expr), exprCollation((Node *) tle->expr)); /* * It's possible that the column is of a collatable type but the * collation could not be resolved, so double-check. */ if (type_is_collatable(exprType((Node *) tle->expr))) { if (!OidIsValid(def->collOid)) ereport(ERROR, (errcode(ERRCODE_INDETERMINATE_COLLATION), errmsg("could not determine which collation to use for view column \"%s\"", def->colname), errhint("Use the COLLATE clause to set the collation explicitly."))); } else Assert(!OidIsValid(def->collOid)); attrList = lappend(attrList, def); } }