/*-------------------------------------------------------------------- * Symbols referenced in this file: * - makeDefElem * - makeTypeNameFromNameList * - makeDefElemExtended * - makeRangeVar * - makeVacuumRelation * - makeAlias * - makeSimpleA_Expr * - makeGroupingSet * - makeTypeName * - makeFuncCall * - makeA_Expr * - makeJsonFormat * - makeJsonIsPredicate * - makeJsonValueExpr * - makeJsonEncoding * - makeJsonKeyValue * - makeBoolExpr *-------------------------------------------------------------------- */ /*------------------------------------------------------------------------- * * makefuncs.c * creator functions for various nodes. The functions here are for the * most frequently created nodes. * * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * src/backend/nodes/makefuncs.c * *------------------------------------------------------------------------- */ #include "postgres.h" #include "catalog/pg_class.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "utils/errcodes.h" #include "utils/lsyscache.h" /* * makeA_Expr - * makes an A_Expr node */ A_Expr * makeA_Expr(A_Expr_Kind kind, List *name, Node *lexpr, Node *rexpr, int location) { A_Expr *a = makeNode(A_Expr); a->kind = kind; a->name = name; a->lexpr = lexpr; a->rexpr = rexpr; a->location = location; return a; } /* * makeSimpleA_Expr - * As above, given a simple (unqualified) operator name */ A_Expr * makeSimpleA_Expr(A_Expr_Kind kind, char *name, Node *lexpr, Node *rexpr, int location) { A_Expr *a = makeNode(A_Expr); a->kind = kind; a->name = list_make1(makeString((char *) name)); a->lexpr = lexpr; a->rexpr = rexpr; a->location = location; return a; } /* * makeVar - * creates a Var node */ /* * makeVarFromTargetEntry - * convenience function to create a same-level Var node from a * TargetEntry */ /* * makeWholeRowVar - * creates a Var node representing a whole row of the specified RTE * * A whole-row reference is a Var with varno set to the correct range * table entry, and varattno == 0 to signal that it references the whole * tuple. (Use of zero here is unclean, since it could easily be confused * with error cases, but it's not worth changing now.) The vartype indicates * a rowtype; either a named composite type, or a domain over a named * composite type (only possible if the RTE is a function returning that), * or RECORD. This function encapsulates the logic for determining the * correct rowtype OID to use. * * If allowScalar is true, then for the case where the RTE is a single function * returning a non-composite result type, we produce a normal Var referencing * the function's result directly, instead of the single-column composite * value that the whole-row notation might otherwise suggest. */ /* * makeTargetEntry - * creates a TargetEntry node */ /* * flatCopyTargetEntry - * duplicate a TargetEntry, but don't copy substructure * * This is commonly used when we just want to modify the resno or substitute * a new expression. */ /* * makeFromExpr - * creates a FromExpr node */ /* * makeConst - * creates a Const node */ /* * makeNullConst - * creates a Const node representing a NULL of the specified type/typmod * * This is a convenience routine that just saves a lookup of the type's * storage properties. */ /* * makeBoolConst - * creates a Const node representing a boolean value (can be NULL too) */ /* * makeBoolExpr - * creates a BoolExpr node */ Expr * makeBoolExpr(BoolExprType boolop, List *args, int location) { BoolExpr *b = makeNode(BoolExpr); b->boolop = boolop; b->args = args; b->location = location; return (Expr *) b; } /* * makeAlias - * creates an Alias node * * NOTE: the given name is copied, but the colnames list (if any) isn't. */ Alias * makeAlias(const char *aliasname, List *colnames) { Alias *a = makeNode(Alias); a->aliasname = pstrdup(aliasname); a->colnames = colnames; return a; } /* * makeRelabelType - * creates a RelabelType node */ /* * makeRangeVar - * creates a RangeVar node (rather oversimplified case) */ RangeVar * makeRangeVar(char *schemaname, char *relname, int location) { RangeVar *r = makeNode(RangeVar); r->catalogname = NULL; r->schemaname = schemaname; r->relname = relname; r->inh = true; r->relpersistence = RELPERSISTENCE_PERMANENT; r->alias = NULL; r->location = location; return r; } /* * makeTypeName - * build a TypeName node for an unqualified name. * * typmod is defaulted, but can be changed later by caller. */ TypeName * makeTypeName(char *typnam) { return makeTypeNameFromNameList(list_make1(makeString(typnam))); } /* * makeTypeNameFromNameList - * build a TypeName node for a String list representing a qualified name. * * typmod is defaulted, but can be changed later by caller. */ TypeName * makeTypeNameFromNameList(List *names) { TypeName *n = makeNode(TypeName); n->names = names; n->typmods = NIL; n->typemod = -1; n->location = -1; return n; } /* * makeTypeNameFromOid - * build a TypeName node to represent a type already known by OID/typmod. */ /* * makeColumnDef - * build a ColumnDef node to represent a simple column definition. * * Type and collation are specified by OID. * Other properties are all basic to start with. */ /* * makeFuncExpr - * build an expression tree representing a function call. * * The argument expressions must have been transformed already. */ /* * makeDefElem - * build a DefElem node * * This is sufficient for the "typical" case with an unqualified option name * and no special action. */ DefElem * makeDefElem(char *name, Node *arg, int location) { DefElem *res = makeNode(DefElem); res->defnamespace = NULL; res->defname = name; res->arg = arg; res->defaction = DEFELEM_UNSPEC; res->location = location; return res; } /* * makeDefElemExtended - * build a DefElem node with all fields available to be specified */ DefElem * makeDefElemExtended(char *nameSpace, char *name, Node *arg, DefElemAction defaction, int location) { DefElem *res = makeNode(DefElem); res->defnamespace = nameSpace; res->defname = name; res->arg = arg; res->defaction = defaction; res->location = location; return res; } /* * makeFuncCall - * * Initialize a FuncCall struct with the information every caller must * supply. Any non-default parameters have to be inserted by the caller. */ FuncCall * makeFuncCall(List *name, List *args, CoercionForm funcformat, int location) { FuncCall *n = makeNode(FuncCall); n->funcname = name; n->args = args; n->agg_order = NIL; n->agg_filter = NULL; n->over = NULL; n->agg_within_group = false; n->agg_star = false; n->agg_distinct = false; n->func_variadic = false; n->funcformat = funcformat; n->location = location; return n; } /* * make_opclause * Creates an operator clause given its operator info, left operand * and right operand (pass NULL to create single-operand clause), * and collation info. */ /* * make_andclause * * Creates an 'and' clause given a list of its subclauses. */ /* * make_orclause * * Creates an 'or' clause given a list of its subclauses. */ /* * make_notclause * * Create a 'not' clause given the expression to be negated. */ /* * make_and_qual * * Variant of make_andclause for ANDing two qual conditions together. * Qual conditions have the property that a NULL nodetree is interpreted * as 'true'. * * NB: this makes no attempt to preserve AND/OR flatness; so it should not * be used on a qual that has already been run through prepqual.c. */ /* * The planner and executor usually represent qualification expressions * as lists of boolean expressions with implicit AND semantics. * * These functions convert between an AND-semantics expression list and the * ordinary representation of a boolean expression. * * Note that an empty list is considered equivalent to TRUE. */ /* * makeIndexInfo * create an IndexInfo node */ /* * makeGroupingSet * */ GroupingSet * makeGroupingSet(GroupingSetKind kind, List *content, int location) { GroupingSet *n = makeNode(GroupingSet); n->kind = kind; n->content = content; n->location = location; return n; } /* * makeVacuumRelation - * create a VacuumRelation node */ VacuumRelation * makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols) { VacuumRelation *v = makeNode(VacuumRelation); v->relation = relation; v->oid = oid; v->va_cols = va_cols; return v; } /* * makeJsonFormat - * creates a JsonFormat node */ JsonFormat * makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location) { JsonFormat *jf = makeNode(JsonFormat); jf->format_type = type; jf->encoding = encoding; jf->location = location; return jf; } /* * makeJsonValueExpr - * creates a JsonValueExpr node */ JsonValueExpr * makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr, JsonFormat *format) { JsonValueExpr *jve = makeNode(JsonValueExpr); jve->raw_expr = raw_expr; jve->formatted_expr = formatted_expr; jve->format = format; return jve; } /* * makeJsonEncoding - * converts JSON encoding name to enum JsonEncoding */ JsonEncoding makeJsonEncoding(char *name) { if (!pg_strcasecmp(name, "utf8")) return JS_ENC_UTF8; if (!pg_strcasecmp(name, "utf16")) return JS_ENC_UTF16; if (!pg_strcasecmp(name, "utf32")) return JS_ENC_UTF32; ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unrecognized JSON encoding: %s", name)); return JS_ENC_DEFAULT; } /* * makeJsonKeyValue - * creates a JsonKeyValue node */ Node * makeJsonKeyValue(Node *key, Node *value) { JsonKeyValue *n = makeNode(JsonKeyValue); n->key = (Expr *) key; n->value = castNode(JsonValueExpr, value); return (Node *) n; } /* * makeJsonIsPredicate - * creates a JsonIsPredicate node */ Node * makeJsonIsPredicate(Node *expr, JsonFormat *format, JsonValueType item_type, bool unique_keys, int location) { JsonIsPredicate *n = makeNode(JsonIsPredicate); n->expr = expr; n->format = format; n->item_type = item_type; n->unique_keys = unique_keys; n->location = location; return (Node *) n; }