| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * define.c |
| 4 | * Support routines for various kinds of object creation. |
| 5 | * |
| 6 | * |
| 7 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 8 | * Portions Copyright (c) 1994, Regents of the University of California |
| 9 | * |
| 10 | * |
| 11 | * IDENTIFICATION |
| 12 | * src/backend/commands/define.c |
| 13 | * |
| 14 | * DESCRIPTION |
| 15 | * The "DefineFoo" routines take the parse tree and pick out the |
| 16 | * appropriate arguments/flags, passing the results to the |
| 17 | * corresponding "FooDefine" routines (in src/catalog) that do |
| 18 | * the actual catalog-munging. These routines also verify permission |
| 19 | * of the user to execute the command. |
| 20 | * |
| 21 | * NOTES |
| 22 | * These things must be defined and committed in the following order: |
| 23 | * "create function": |
| 24 | * input/output, recv/send procedures |
| 25 | * "create type": |
| 26 | * type |
| 27 | * "create operator": |
| 28 | * operators |
| 29 | * |
| 30 | * |
| 31 | *------------------------------------------------------------------------- |
| 32 | */ |
| 33 | #include "postgres.h" |
| 34 | |
| 35 | #include <ctype.h> |
| 36 | #include <math.h> |
| 37 | |
| 38 | #include "catalog/namespace.h" |
| 39 | #include "commands/defrem.h" |
| 40 | #include "nodes/makefuncs.h" |
| 41 | #include "parser/parse_type.h" |
| 42 | #include "parser/scansup.h" |
| 43 | #include "utils/builtins.h" |
| 44 | |
| 45 | /* |
| 46 | * Extract a string value (otherwise uninterpreted) from a DefElem. |
| 47 | */ |
| 48 | char * |
| 49 | defGetString(DefElem *def) |
| 50 | { |
| 51 | if (def->arg == NULL) |
| 52 | ereport(ERROR, |
| 53 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 54 | errmsg("%s requires a parameter" , |
| 55 | def->defname))); |
| 56 | switch (nodeTag(def->arg)) |
| 57 | { |
| 58 | case T_Integer: |
| 59 | return psprintf("%ld" , (long) intVal(def->arg)); |
| 60 | case T_Float: |
| 61 | |
| 62 | /* |
| 63 | * T_Float values are kept in string form, so this type cheat |
| 64 | * works (and doesn't risk losing precision) |
| 65 | */ |
| 66 | return strVal(def->arg); |
| 67 | case T_String: |
| 68 | return strVal(def->arg); |
| 69 | case T_TypeName: |
| 70 | return TypeNameToString((TypeName *) def->arg); |
| 71 | case T_List: |
| 72 | return NameListToString((List *) def->arg); |
| 73 | case T_A_Star: |
| 74 | return pstrdup("*" ); |
| 75 | default: |
| 76 | elog(ERROR, "unrecognized node type: %d" , (int) nodeTag(def->arg)); |
| 77 | } |
| 78 | return NULL; /* keep compiler quiet */ |
| 79 | } |
| 80 | |
| 81 | /* |
| 82 | * Extract a numeric value (actually double) from a DefElem. |
| 83 | */ |
| 84 | double |
| 85 | defGetNumeric(DefElem *def) |
| 86 | { |
| 87 | if (def->arg == NULL) |
| 88 | ereport(ERROR, |
| 89 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 90 | errmsg("%s requires a numeric value" , |
| 91 | def->defname))); |
| 92 | switch (nodeTag(def->arg)) |
| 93 | { |
| 94 | case T_Integer: |
| 95 | return (double) intVal(def->arg); |
| 96 | case T_Float: |
| 97 | return floatVal(def->arg); |
| 98 | default: |
| 99 | ereport(ERROR, |
| 100 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 101 | errmsg("%s requires a numeric value" , |
| 102 | def->defname))); |
| 103 | } |
| 104 | return 0; /* keep compiler quiet */ |
| 105 | } |
| 106 | |
| 107 | /* |
| 108 | * Extract a boolean value from a DefElem. |
| 109 | */ |
| 110 | bool |
| 111 | defGetBoolean(DefElem *def) |
| 112 | { |
| 113 | /* |
| 114 | * If no parameter given, assume "true" is meant. |
| 115 | */ |
| 116 | if (def->arg == NULL) |
| 117 | return true; |
| 118 | |
| 119 | /* |
| 120 | * Allow 0, 1, "true", "false", "on", "off" |
| 121 | */ |
| 122 | switch (nodeTag(def->arg)) |
| 123 | { |
| 124 | case T_Integer: |
| 125 | switch (intVal(def->arg)) |
| 126 | { |
| 127 | case 0: |
| 128 | return false; |
| 129 | case 1: |
| 130 | return true; |
| 131 | default: |
| 132 | /* otherwise, error out below */ |
| 133 | break; |
| 134 | } |
| 135 | break; |
| 136 | default: |
| 137 | { |
| 138 | char *sval = defGetString(def); |
| 139 | |
| 140 | /* |
| 141 | * The set of strings accepted here should match up with the |
| 142 | * grammar's opt_boolean production. |
| 143 | */ |
| 144 | if (pg_strcasecmp(sval, "true" ) == 0) |
| 145 | return true; |
| 146 | if (pg_strcasecmp(sval, "false" ) == 0) |
| 147 | return false; |
| 148 | if (pg_strcasecmp(sval, "on" ) == 0) |
| 149 | return true; |
| 150 | if (pg_strcasecmp(sval, "off" ) == 0) |
| 151 | return false; |
| 152 | } |
| 153 | break; |
| 154 | } |
| 155 | ereport(ERROR, |
| 156 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 157 | errmsg("%s requires a Boolean value" , |
| 158 | def->defname))); |
| 159 | return false; /* keep compiler quiet */ |
| 160 | } |
| 161 | |
| 162 | /* |
| 163 | * Extract an int32 value from a DefElem. |
| 164 | */ |
| 165 | int32 |
| 166 | defGetInt32(DefElem *def) |
| 167 | { |
| 168 | if (def->arg == NULL) |
| 169 | ereport(ERROR, |
| 170 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 171 | errmsg("%s requires an integer value" , |
| 172 | def->defname))); |
| 173 | switch (nodeTag(def->arg)) |
| 174 | { |
| 175 | case T_Integer: |
| 176 | return (int32) intVal(def->arg); |
| 177 | default: |
| 178 | ereport(ERROR, |
| 179 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 180 | errmsg("%s requires an integer value" , |
| 181 | def->defname))); |
| 182 | } |
| 183 | return 0; /* keep compiler quiet */ |
| 184 | } |
| 185 | |
| 186 | /* |
| 187 | * Extract an int64 value from a DefElem. |
| 188 | */ |
| 189 | int64 |
| 190 | defGetInt64(DefElem *def) |
| 191 | { |
| 192 | if (def->arg == NULL) |
| 193 | ereport(ERROR, |
| 194 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 195 | errmsg("%s requires a numeric value" , |
| 196 | def->defname))); |
| 197 | switch (nodeTag(def->arg)) |
| 198 | { |
| 199 | case T_Integer: |
| 200 | return (int64) intVal(def->arg); |
| 201 | case T_Float: |
| 202 | |
| 203 | /* |
| 204 | * Values too large for int4 will be represented as Float |
| 205 | * constants by the lexer. Accept these if they are valid int8 |
| 206 | * strings. |
| 207 | */ |
| 208 | return DatumGetInt64(DirectFunctionCall1(int8in, |
| 209 | CStringGetDatum(strVal(def->arg)))); |
| 210 | default: |
| 211 | ereport(ERROR, |
| 212 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 213 | errmsg("%s requires a numeric value" , |
| 214 | def->defname))); |
| 215 | } |
| 216 | return 0; /* keep compiler quiet */ |
| 217 | } |
| 218 | |
| 219 | /* |
| 220 | * Extract a possibly-qualified name (as a List of Strings) from a DefElem. |
| 221 | */ |
| 222 | List * |
| 223 | defGetQualifiedName(DefElem *def) |
| 224 | { |
| 225 | if (def->arg == NULL) |
| 226 | ereport(ERROR, |
| 227 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 228 | errmsg("%s requires a parameter" , |
| 229 | def->defname))); |
| 230 | switch (nodeTag(def->arg)) |
| 231 | { |
| 232 | case T_TypeName: |
| 233 | return ((TypeName *) def->arg)->names; |
| 234 | case T_List: |
| 235 | return (List *) def->arg; |
| 236 | case T_String: |
| 237 | /* Allow quoted name for backwards compatibility */ |
| 238 | return list_make1(def->arg); |
| 239 | default: |
| 240 | ereport(ERROR, |
| 241 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 242 | errmsg("argument of %s must be a name" , |
| 243 | def->defname))); |
| 244 | } |
| 245 | return NIL; /* keep compiler quiet */ |
| 246 | } |
| 247 | |
| 248 | /* |
| 249 | * Extract a TypeName from a DefElem. |
| 250 | * |
| 251 | * Note: we do not accept a List arg here, because the parser will only |
| 252 | * return a bare List when the name looks like an operator name. |
| 253 | */ |
| 254 | TypeName * |
| 255 | defGetTypeName(DefElem *def) |
| 256 | { |
| 257 | if (def->arg == NULL) |
| 258 | ereport(ERROR, |
| 259 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 260 | errmsg("%s requires a parameter" , |
| 261 | def->defname))); |
| 262 | switch (nodeTag(def->arg)) |
| 263 | { |
| 264 | case T_TypeName: |
| 265 | return (TypeName *) def->arg; |
| 266 | case T_String: |
| 267 | /* Allow quoted typename for backwards compatibility */ |
| 268 | return makeTypeNameFromNameList(list_make1(def->arg)); |
| 269 | default: |
| 270 | ereport(ERROR, |
| 271 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 272 | errmsg("argument of %s must be a type name" , |
| 273 | def->defname))); |
| 274 | } |
| 275 | return NULL; /* keep compiler quiet */ |
| 276 | } |
| 277 | |
| 278 | /* |
| 279 | * Extract a type length indicator (either absolute bytes, or |
| 280 | * -1 for "variable") from a DefElem. |
| 281 | */ |
| 282 | int |
| 283 | defGetTypeLength(DefElem *def) |
| 284 | { |
| 285 | if (def->arg == NULL) |
| 286 | ereport(ERROR, |
| 287 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 288 | errmsg("%s requires a parameter" , |
| 289 | def->defname))); |
| 290 | switch (nodeTag(def->arg)) |
| 291 | { |
| 292 | case T_Integer: |
| 293 | return intVal(def->arg); |
| 294 | case T_Float: |
| 295 | ereport(ERROR, |
| 296 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 297 | errmsg("%s requires an integer value" , |
| 298 | def->defname))); |
| 299 | break; |
| 300 | case T_String: |
| 301 | if (pg_strcasecmp(strVal(def->arg), "variable" ) == 0) |
| 302 | return -1; /* variable length */ |
| 303 | break; |
| 304 | case T_TypeName: |
| 305 | /* cope if grammar chooses to believe "variable" is a typename */ |
| 306 | if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg), |
| 307 | "variable" ) == 0) |
| 308 | return -1; /* variable length */ |
| 309 | break; |
| 310 | case T_List: |
| 311 | /* must be an operator name */ |
| 312 | break; |
| 313 | default: |
| 314 | elog(ERROR, "unrecognized node type: %d" , (int) nodeTag(def->arg)); |
| 315 | } |
| 316 | ereport(ERROR, |
| 317 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 318 | errmsg("invalid argument for %s: \"%s\"" , |
| 319 | def->defname, defGetString(def)))); |
| 320 | return 0; /* keep compiler quiet */ |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | * Extract a list of string values (otherwise uninterpreted) from a DefElem. |
| 325 | */ |
| 326 | List * |
| 327 | defGetStringList(DefElem *def) |
| 328 | { |
| 329 | ListCell *cell; |
| 330 | |
| 331 | if (def->arg == NULL) |
| 332 | ereport(ERROR, |
| 333 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 334 | errmsg("%s requires a parameter" , |
| 335 | def->defname))); |
| 336 | if (nodeTag(def->arg) != T_List) |
| 337 | elog(ERROR, "unrecognized node type: %d" , (int) nodeTag(def->arg)); |
| 338 | |
| 339 | foreach(cell, (List *) def->arg) |
| 340 | { |
| 341 | Node *str = (Node *) lfirst(cell); |
| 342 | |
| 343 | if (!IsA(str, String)) |
| 344 | elog(ERROR, "unexpected node type in name list: %d" , |
| 345 | (int) nodeTag(str)); |
| 346 | } |
| 347 | |
| 348 | return (List *) def->arg; |
| 349 | } |
| 350 | |