| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * nodes.h |
| 4 | * Definitions for tagged nodes. |
| 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 | * src/include/nodes/nodes.h |
| 11 | * |
| 12 | *------------------------------------------------------------------------- |
| 13 | */ |
| 14 | #ifndef NODES_H |
| 15 | #define NODES_H |
| 16 | |
| 17 | /* |
| 18 | * The first field of every node is NodeTag. Each node created (with makeNode) |
| 19 | * will have one of the following tags as the value of its first field. |
| 20 | * |
| 21 | * Note that inserting or deleting node types changes the numbers of other |
| 22 | * node types later in the list. This is no problem during development, since |
| 23 | * the node numbers are never stored on disk. But don't do it in a released |
| 24 | * branch, because that would represent an ABI break for extensions. |
| 25 | */ |
| 26 | typedef enum NodeTag |
| 27 | { |
| 28 | T_Invalid = 0, |
| 29 | |
| 30 | /* |
| 31 | * TAGS FOR EXECUTOR NODES (execnodes.h) |
| 32 | */ |
| 33 | T_IndexInfo, |
| 34 | T_ExprContext, |
| 35 | T_ProjectionInfo, |
| 36 | T_JunkFilter, |
| 37 | T_OnConflictSetState, |
| 38 | T_ResultRelInfo, |
| 39 | T_EState, |
| 40 | T_TupleTableSlot, |
| 41 | |
| 42 | /* |
| 43 | * TAGS FOR PLAN NODES (plannodes.h) |
| 44 | */ |
| 45 | T_Plan, |
| 46 | T_Result, |
| 47 | T_ProjectSet, |
| 48 | T_ModifyTable, |
| 49 | T_Append, |
| 50 | T_MergeAppend, |
| 51 | T_RecursiveUnion, |
| 52 | T_BitmapAnd, |
| 53 | T_BitmapOr, |
| 54 | T_Scan, |
| 55 | T_SeqScan, |
| 56 | T_SampleScan, |
| 57 | T_IndexScan, |
| 58 | T_IndexOnlyScan, |
| 59 | T_BitmapIndexScan, |
| 60 | T_BitmapHeapScan, |
| 61 | T_TidScan, |
| 62 | T_SubqueryScan, |
| 63 | T_FunctionScan, |
| 64 | T_ValuesScan, |
| 65 | T_TableFuncScan, |
| 66 | T_CteScan, |
| 67 | T_NamedTuplestoreScan, |
| 68 | T_WorkTableScan, |
| 69 | T_ForeignScan, |
| 70 | T_CustomScan, |
| 71 | T_Join, |
| 72 | T_NestLoop, |
| 73 | T_MergeJoin, |
| 74 | T_HashJoin, |
| 75 | T_Material, |
| 76 | T_Sort, |
| 77 | T_Group, |
| 78 | T_Agg, |
| 79 | T_WindowAgg, |
| 80 | T_Unique, |
| 81 | T_Gather, |
| 82 | T_GatherMerge, |
| 83 | T_Hash, |
| 84 | T_SetOp, |
| 85 | T_LockRows, |
| 86 | T_Limit, |
| 87 | /* these aren't subclasses of Plan: */ |
| 88 | T_NestLoopParam, |
| 89 | T_PlanRowMark, |
| 90 | T_PartitionPruneInfo, |
| 91 | T_PartitionedRelPruneInfo, |
| 92 | T_PartitionPruneStepOp, |
| 93 | T_PartitionPruneStepCombine, |
| 94 | T_PlanInvalItem, |
| 95 | |
| 96 | /* |
| 97 | * TAGS FOR PLAN STATE NODES (execnodes.h) |
| 98 | * |
| 99 | * These should correspond one-to-one with Plan node types. |
| 100 | */ |
| 101 | T_PlanState, |
| 102 | T_ResultState, |
| 103 | T_ProjectSetState, |
| 104 | T_ModifyTableState, |
| 105 | T_AppendState, |
| 106 | T_MergeAppendState, |
| 107 | T_RecursiveUnionState, |
| 108 | T_BitmapAndState, |
| 109 | T_BitmapOrState, |
| 110 | T_ScanState, |
| 111 | T_SeqScanState, |
| 112 | T_SampleScanState, |
| 113 | T_IndexScanState, |
| 114 | T_IndexOnlyScanState, |
| 115 | T_BitmapIndexScanState, |
| 116 | T_BitmapHeapScanState, |
| 117 | T_TidScanState, |
| 118 | T_SubqueryScanState, |
| 119 | T_FunctionScanState, |
| 120 | T_TableFuncScanState, |
| 121 | T_ValuesScanState, |
| 122 | T_CteScanState, |
| 123 | T_NamedTuplestoreScanState, |
| 124 | T_WorkTableScanState, |
| 125 | T_ForeignScanState, |
| 126 | T_CustomScanState, |
| 127 | T_JoinState, |
| 128 | T_NestLoopState, |
| 129 | T_MergeJoinState, |
| 130 | T_HashJoinState, |
| 131 | T_MaterialState, |
| 132 | T_SortState, |
| 133 | T_GroupState, |
| 134 | T_AggState, |
| 135 | T_WindowAggState, |
| 136 | T_UniqueState, |
| 137 | T_GatherState, |
| 138 | T_GatherMergeState, |
| 139 | T_HashState, |
| 140 | T_SetOpState, |
| 141 | T_LockRowsState, |
| 142 | T_LimitState, |
| 143 | |
| 144 | /* |
| 145 | * TAGS FOR PRIMITIVE NODES (primnodes.h) |
| 146 | */ |
| 147 | T_Alias, |
| 148 | T_RangeVar, |
| 149 | T_TableFunc, |
| 150 | T_Expr, |
| 151 | T_Var, |
| 152 | T_Const, |
| 153 | T_Param, |
| 154 | T_Aggref, |
| 155 | T_GroupingFunc, |
| 156 | T_WindowFunc, |
| 157 | T_SubscriptingRef, |
| 158 | T_FuncExpr, |
| 159 | T_NamedArgExpr, |
| 160 | T_OpExpr, |
| 161 | T_DistinctExpr, |
| 162 | T_NullIfExpr, |
| 163 | T_ScalarArrayOpExpr, |
| 164 | T_BoolExpr, |
| 165 | T_SubLink, |
| 166 | T_SubPlan, |
| 167 | T_AlternativeSubPlan, |
| 168 | T_FieldSelect, |
| 169 | T_FieldStore, |
| 170 | T_RelabelType, |
| 171 | T_CoerceViaIO, |
| 172 | T_ArrayCoerceExpr, |
| 173 | T_ConvertRowtypeExpr, |
| 174 | T_CollateExpr, |
| 175 | T_CaseExpr, |
| 176 | T_CaseWhen, |
| 177 | T_CaseTestExpr, |
| 178 | T_ArrayExpr, |
| 179 | T_RowExpr, |
| 180 | T_RowCompareExpr, |
| 181 | T_CoalesceExpr, |
| 182 | T_MinMaxExpr, |
| 183 | T_SQLValueFunction, |
| 184 | T_XmlExpr, |
| 185 | T_NullTest, |
| 186 | T_BooleanTest, |
| 187 | T_CoerceToDomain, |
| 188 | T_CoerceToDomainValue, |
| 189 | T_SetToDefault, |
| 190 | T_CurrentOfExpr, |
| 191 | T_NextValueExpr, |
| 192 | T_InferenceElem, |
| 193 | T_TargetEntry, |
| 194 | T_RangeTblRef, |
| 195 | T_JoinExpr, |
| 196 | T_FromExpr, |
| 197 | T_OnConflictExpr, |
| 198 | T_IntoClause, |
| 199 | |
| 200 | /* |
| 201 | * TAGS FOR EXPRESSION STATE NODES (execnodes.h) |
| 202 | * |
| 203 | * ExprState represents the evaluation state for a whole expression tree. |
| 204 | * Most Expr-based plan nodes do not have a corresponding expression state |
| 205 | * node, they're fully handled within execExpr* - but sometimes the state |
| 206 | * needs to be shared with other parts of the executor, as for example |
| 207 | * with AggrefExprState, which nodeAgg.c has to modify. |
| 208 | */ |
| 209 | T_ExprState, |
| 210 | T_AggrefExprState, |
| 211 | T_WindowFuncExprState, |
| 212 | T_SetExprState, |
| 213 | T_SubPlanState, |
| 214 | T_AlternativeSubPlanState, |
| 215 | T_DomainConstraintState, |
| 216 | |
| 217 | /* |
| 218 | * TAGS FOR PLANNER NODES (pathnodes.h) |
| 219 | */ |
| 220 | T_PlannerInfo, |
| 221 | T_PlannerGlobal, |
| 222 | T_RelOptInfo, |
| 223 | T_IndexOptInfo, |
| 224 | T_ForeignKeyOptInfo, |
| 225 | T_ParamPathInfo, |
| 226 | T_Path, |
| 227 | T_IndexPath, |
| 228 | T_BitmapHeapPath, |
| 229 | T_BitmapAndPath, |
| 230 | T_BitmapOrPath, |
| 231 | T_TidPath, |
| 232 | T_SubqueryScanPath, |
| 233 | T_ForeignPath, |
| 234 | T_CustomPath, |
| 235 | T_NestPath, |
| 236 | T_MergePath, |
| 237 | T_HashPath, |
| 238 | T_AppendPath, |
| 239 | T_MergeAppendPath, |
| 240 | T_GroupResultPath, |
| 241 | T_MaterialPath, |
| 242 | T_UniquePath, |
| 243 | T_GatherPath, |
| 244 | T_GatherMergePath, |
| 245 | T_ProjectionPath, |
| 246 | T_ProjectSetPath, |
| 247 | T_SortPath, |
| 248 | T_GroupPath, |
| 249 | T_UpperUniquePath, |
| 250 | T_AggPath, |
| 251 | T_GroupingSetsPath, |
| 252 | T_MinMaxAggPath, |
| 253 | T_WindowAggPath, |
| 254 | T_SetOpPath, |
| 255 | T_RecursiveUnionPath, |
| 256 | T_LockRowsPath, |
| 257 | T_ModifyTablePath, |
| 258 | T_LimitPath, |
| 259 | /* these aren't subclasses of Path: */ |
| 260 | T_EquivalenceClass, |
| 261 | T_EquivalenceMember, |
| 262 | T_PathKey, |
| 263 | T_PathTarget, |
| 264 | T_RestrictInfo, |
| 265 | T_IndexClause, |
| 266 | T_PlaceHolderVar, |
| 267 | T_SpecialJoinInfo, |
| 268 | T_AppendRelInfo, |
| 269 | T_PlaceHolderInfo, |
| 270 | T_MinMaxAggInfo, |
| 271 | T_PlannerParamItem, |
| 272 | T_RollupData, |
| 273 | T_GroupingSetData, |
| 274 | T_StatisticExtInfo, |
| 275 | |
| 276 | /* |
| 277 | * TAGS FOR MEMORY NODES (memnodes.h) |
| 278 | */ |
| 279 | T_MemoryContext, |
| 280 | T_AllocSetContext, |
| 281 | T_SlabContext, |
| 282 | T_GenerationContext, |
| 283 | |
| 284 | /* |
| 285 | * TAGS FOR VALUE NODES (value.h) |
| 286 | */ |
| 287 | T_Value, |
| 288 | T_Integer, |
| 289 | T_Float, |
| 290 | T_String, |
| 291 | T_BitString, |
| 292 | T_Null, |
| 293 | |
| 294 | /* |
| 295 | * TAGS FOR LIST NODES (pg_list.h) |
| 296 | */ |
| 297 | T_List, |
| 298 | T_IntList, |
| 299 | T_OidList, |
| 300 | |
| 301 | /* |
| 302 | * TAGS FOR EXTENSIBLE NODES (extensible.h) |
| 303 | */ |
| 304 | T_ExtensibleNode, |
| 305 | |
| 306 | /* |
| 307 | * TAGS FOR STATEMENT NODES (mostly in parsenodes.h) |
| 308 | */ |
| 309 | T_RawStmt, |
| 310 | T_Query, |
| 311 | T_PlannedStmt, |
| 312 | T_InsertStmt, |
| 313 | T_DeleteStmt, |
| 314 | T_UpdateStmt, |
| 315 | T_SelectStmt, |
| 316 | T_AlterTableStmt, |
| 317 | T_AlterTableCmd, |
| 318 | T_AlterDomainStmt, |
| 319 | T_SetOperationStmt, |
| 320 | T_GrantStmt, |
| 321 | T_GrantRoleStmt, |
| 322 | T_AlterDefaultPrivilegesStmt, |
| 323 | T_ClosePortalStmt, |
| 324 | T_ClusterStmt, |
| 325 | T_CopyStmt, |
| 326 | T_CreateStmt, |
| 327 | T_DefineStmt, |
| 328 | T_DropStmt, |
| 329 | T_TruncateStmt, |
| 330 | , |
| 331 | T_FetchStmt, |
| 332 | T_IndexStmt, |
| 333 | T_CreateFunctionStmt, |
| 334 | T_AlterFunctionStmt, |
| 335 | T_DoStmt, |
| 336 | T_RenameStmt, |
| 337 | T_RuleStmt, |
| 338 | T_NotifyStmt, |
| 339 | T_ListenStmt, |
| 340 | T_UnlistenStmt, |
| 341 | T_TransactionStmt, |
| 342 | T_ViewStmt, |
| 343 | T_LoadStmt, |
| 344 | T_CreateDomainStmt, |
| 345 | T_CreatedbStmt, |
| 346 | T_DropdbStmt, |
| 347 | T_VacuumStmt, |
| 348 | T_ExplainStmt, |
| 349 | T_CreateTableAsStmt, |
| 350 | T_CreateSeqStmt, |
| 351 | T_AlterSeqStmt, |
| 352 | T_VariableSetStmt, |
| 353 | T_VariableShowStmt, |
| 354 | T_DiscardStmt, |
| 355 | T_CreateTrigStmt, |
| 356 | T_CreatePLangStmt, |
| 357 | T_CreateRoleStmt, |
| 358 | T_AlterRoleStmt, |
| 359 | T_DropRoleStmt, |
| 360 | T_LockStmt, |
| 361 | T_ConstraintsSetStmt, |
| 362 | T_ReindexStmt, |
| 363 | T_CheckPointStmt, |
| 364 | T_CreateSchemaStmt, |
| 365 | T_AlterDatabaseStmt, |
| 366 | T_AlterDatabaseSetStmt, |
| 367 | T_AlterRoleSetStmt, |
| 368 | T_CreateConversionStmt, |
| 369 | T_CreateCastStmt, |
| 370 | T_CreateOpClassStmt, |
| 371 | T_CreateOpFamilyStmt, |
| 372 | T_AlterOpFamilyStmt, |
| 373 | T_PrepareStmt, |
| 374 | T_ExecuteStmt, |
| 375 | T_DeallocateStmt, |
| 376 | T_DeclareCursorStmt, |
| 377 | T_CreateTableSpaceStmt, |
| 378 | T_DropTableSpaceStmt, |
| 379 | T_AlterObjectDependsStmt, |
| 380 | T_AlterObjectSchemaStmt, |
| 381 | T_AlterOwnerStmt, |
| 382 | T_AlterOperatorStmt, |
| 383 | T_DropOwnedStmt, |
| 384 | T_ReassignOwnedStmt, |
| 385 | T_CompositeTypeStmt, |
| 386 | T_CreateEnumStmt, |
| 387 | T_CreateRangeStmt, |
| 388 | T_AlterEnumStmt, |
| 389 | T_AlterTSDictionaryStmt, |
| 390 | T_AlterTSConfigurationStmt, |
| 391 | T_CreateFdwStmt, |
| 392 | T_AlterFdwStmt, |
| 393 | T_CreateForeignServerStmt, |
| 394 | T_AlterForeignServerStmt, |
| 395 | T_CreateUserMappingStmt, |
| 396 | T_AlterUserMappingStmt, |
| 397 | T_DropUserMappingStmt, |
| 398 | T_AlterTableSpaceOptionsStmt, |
| 399 | T_AlterTableMoveAllStmt, |
| 400 | T_SecLabelStmt, |
| 401 | T_CreateForeignTableStmt, |
| 402 | T_ImportForeignSchemaStmt, |
| 403 | T_CreateExtensionStmt, |
| 404 | T_AlterExtensionStmt, |
| 405 | T_AlterExtensionContentsStmt, |
| 406 | T_CreateEventTrigStmt, |
| 407 | T_AlterEventTrigStmt, |
| 408 | T_RefreshMatViewStmt, |
| 409 | T_ReplicaIdentityStmt, |
| 410 | T_AlterSystemStmt, |
| 411 | T_CreatePolicyStmt, |
| 412 | T_AlterPolicyStmt, |
| 413 | T_CreateTransformStmt, |
| 414 | T_CreateAmStmt, |
| 415 | T_CreatePublicationStmt, |
| 416 | T_AlterPublicationStmt, |
| 417 | T_CreateSubscriptionStmt, |
| 418 | T_AlterSubscriptionStmt, |
| 419 | T_DropSubscriptionStmt, |
| 420 | T_CreateStatsStmt, |
| 421 | T_AlterCollationStmt, |
| 422 | T_CallStmt, |
| 423 | |
| 424 | /* |
| 425 | * TAGS FOR PARSE TREE NODES (parsenodes.h) |
| 426 | */ |
| 427 | T_A_Expr, |
| 428 | T_ColumnRef, |
| 429 | T_ParamRef, |
| 430 | T_A_Const, |
| 431 | T_FuncCall, |
| 432 | T_A_Star, |
| 433 | T_A_Indices, |
| 434 | T_A_Indirection, |
| 435 | T_A_ArrayExpr, |
| 436 | T_ResTarget, |
| 437 | T_MultiAssignRef, |
| 438 | T_TypeCast, |
| 439 | T_CollateClause, |
| 440 | T_SortBy, |
| 441 | T_WindowDef, |
| 442 | T_RangeSubselect, |
| 443 | T_RangeFunction, |
| 444 | T_RangeTableSample, |
| 445 | T_RangeTableFunc, |
| 446 | T_RangeTableFuncCol, |
| 447 | T_TypeName, |
| 448 | T_ColumnDef, |
| 449 | T_IndexElem, |
| 450 | T_Constraint, |
| 451 | T_DefElem, |
| 452 | T_RangeTblEntry, |
| 453 | T_RangeTblFunction, |
| 454 | T_TableSampleClause, |
| 455 | T_WithCheckOption, |
| 456 | T_SortGroupClause, |
| 457 | T_GroupingSet, |
| 458 | T_WindowClause, |
| 459 | T_ObjectWithArgs, |
| 460 | T_AccessPriv, |
| 461 | T_CreateOpClassItem, |
| 462 | T_TableLikeClause, |
| 463 | T_FunctionParameter, |
| 464 | T_LockingClause, |
| 465 | T_RowMarkClause, |
| 466 | T_XmlSerialize, |
| 467 | T_WithClause, |
| 468 | T_InferClause, |
| 469 | T_OnConflictClause, |
| 470 | T_CommonTableExpr, |
| 471 | T_RoleSpec, |
| 472 | T_TriggerTransition, |
| 473 | T_PartitionElem, |
| 474 | T_PartitionSpec, |
| 475 | T_PartitionBoundSpec, |
| 476 | T_PartitionRangeDatum, |
| 477 | T_PartitionCmd, |
| 478 | T_VacuumRelation, |
| 479 | |
| 480 | /* |
| 481 | * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h) |
| 482 | */ |
| 483 | T_IdentifySystemCmd, |
| 484 | T_BaseBackupCmd, |
| 485 | T_CreateReplicationSlotCmd, |
| 486 | T_DropReplicationSlotCmd, |
| 487 | T_StartReplicationCmd, |
| 488 | T_TimeLineHistoryCmd, |
| 489 | T_SQLCmd, |
| 490 | |
| 491 | /* |
| 492 | * TAGS FOR RANDOM OTHER STUFF |
| 493 | * |
| 494 | * These are objects that aren't part of parse/plan/execute node tree |
| 495 | * structures, but we give them NodeTags anyway for identification |
| 496 | * purposes (usually because they are involved in APIs where we want to |
| 497 | * pass multiple object types through the same pointer). |
| 498 | */ |
| 499 | T_TriggerData, /* in commands/trigger.h */ |
| 500 | T_EventTriggerData, /* in commands/event_trigger.h */ |
| 501 | T_ReturnSetInfo, /* in nodes/execnodes.h */ |
| 502 | T_WindowObjectData, /* private in nodeWindowAgg.c */ |
| 503 | T_TIDBitmap, /* in nodes/tidbitmap.h */ |
| 504 | T_InlineCodeBlock, /* in nodes/parsenodes.h */ |
| 505 | T_FdwRoutine, /* in foreign/fdwapi.h */ |
| 506 | T_IndexAmRoutine, /* in access/amapi.h */ |
| 507 | T_TableAmRoutine, /* in access/tableam.h */ |
| 508 | T_TsmRoutine, /* in access/tsmapi.h */ |
| 509 | T_ForeignKeyCacheInfo, /* in utils/rel.h */ |
| 510 | T_CallContext, /* in nodes/parsenodes.h */ |
| 511 | T_SupportRequestSimplify, /* in nodes/supportnodes.h */ |
| 512 | T_SupportRequestSelectivity, /* in nodes/supportnodes.h */ |
| 513 | T_SupportRequestCost, /* in nodes/supportnodes.h */ |
| 514 | T_SupportRequestRows, /* in nodes/supportnodes.h */ |
| 515 | T_SupportRequestIndexCondition /* in nodes/supportnodes.h */ |
| 516 | } NodeTag; |
| 517 | |
| 518 | /* |
| 519 | * The first field of a node of any type is guaranteed to be the NodeTag. |
| 520 | * Hence the type of any node can be gotten by casting it to Node. Declaring |
| 521 | * a variable to be of Node * (instead of void *) can also facilitate |
| 522 | * debugging. |
| 523 | */ |
| 524 | typedef struct Node |
| 525 | { |
| 526 | NodeTag type; |
| 527 | } Node; |
| 528 | |
| 529 | #define nodeTag(nodeptr) (((const Node*)(nodeptr))->type) |
| 530 | |
| 531 | /* |
| 532 | * newNode - |
| 533 | * create a new node of the specified size and tag the node with the |
| 534 | * specified tag. |
| 535 | * |
| 536 | * !WARNING!: Avoid using newNode directly. You should be using the |
| 537 | * macro makeNode. eg. to create a Query node, use makeNode(Query) |
| 538 | * |
| 539 | * Note: the size argument should always be a compile-time constant, so the |
| 540 | * apparent risk of multiple evaluation doesn't matter in practice. |
| 541 | */ |
| 542 | #ifdef __GNUC__ |
| 543 | |
| 544 | /* With GCC, we can use a compound statement within an expression */ |
| 545 | #define newNode(size, tag) \ |
| 546 | ({ Node *_result; \ |
| 547 | AssertMacro((size) >= sizeof(Node)); /* need the tag, at least */ \ |
| 548 | _result = (Node *) palloc0fast(size); \ |
| 549 | _result->type = (tag); \ |
| 550 | _result; \ |
| 551 | }) |
| 552 | #else |
| 553 | |
| 554 | /* |
| 555 | * There is no way to dereference the palloc'ed pointer to assign the |
| 556 | * tag, and also return the pointer itself, so we need a holder variable. |
| 557 | * Fortunately, this macro isn't recursive so we just define |
| 558 | * a global variable for this purpose. |
| 559 | */ |
| 560 | extern PGDLLIMPORT Node *newNodeMacroHolder; |
| 561 | |
| 562 | #define newNode(size, tag) \ |
| 563 | ( \ |
| 564 | AssertMacro((size) >= sizeof(Node)), /* need the tag, at least */ \ |
| 565 | newNodeMacroHolder = (Node *) palloc0fast(size), \ |
| 566 | newNodeMacroHolder->type = (tag), \ |
| 567 | newNodeMacroHolder \ |
| 568 | ) |
| 569 | #endif /* __GNUC__ */ |
| 570 | |
| 571 | |
| 572 | #define makeNode(_type_) ((_type_ *) newNode(sizeof(_type_),T_##_type_)) |
| 573 | #define NodeSetTag(nodeptr,t) (((Node*)(nodeptr))->type = (t)) |
| 574 | |
| 575 | #define IsA(nodeptr,_type_) (nodeTag(nodeptr) == T_##_type_) |
| 576 | |
| 577 | /* |
| 578 | * castNode(type, ptr) casts ptr to "type *", and if assertions are enabled, |
| 579 | * verifies that the node has the appropriate type (using its nodeTag()). |
| 580 | * |
| 581 | * Use an inline function when assertions are enabled, to avoid multiple |
| 582 | * evaluations of the ptr argument (which could e.g. be a function call). |
| 583 | */ |
| 584 | #ifdef USE_ASSERT_CHECKING |
| 585 | static inline Node * |
| 586 | castNodeImpl(NodeTag type, void *ptr) |
| 587 | { |
| 588 | Assert(ptr == NULL || nodeTag(ptr) == type); |
| 589 | return (Node *) ptr; |
| 590 | } |
| 591 | #define castNode(_type_, nodeptr) ((_type_ *) castNodeImpl(T_##_type_, nodeptr)) |
| 592 | #else |
| 593 | #define castNode(_type_, nodeptr) ((_type_ *) (nodeptr)) |
| 594 | #endif /* USE_ASSERT_CHECKING */ |
| 595 | |
| 596 | |
| 597 | /* ---------------------------------------------------------------- |
| 598 | * extern declarations follow |
| 599 | * ---------------------------------------------------------------- |
| 600 | */ |
| 601 | |
| 602 | /* |
| 603 | * nodes/{outfuncs.c,print.c} |
| 604 | */ |
| 605 | struct Bitmapset; /* not to include bitmapset.h here */ |
| 606 | struct StringInfoData; /* not to include stringinfo.h here */ |
| 607 | |
| 608 | extern void outNode(struct StringInfoData *str, const void *obj); |
| 609 | extern void outToken(struct StringInfoData *str, const char *s); |
| 610 | extern void outBitmapset(struct StringInfoData *str, |
| 611 | const struct Bitmapset *bms); |
| 612 | extern void outDatum(struct StringInfoData *str, uintptr_t value, |
| 613 | int typlen, bool typbyval); |
| 614 | extern char *nodeToString(const void *obj); |
| 615 | extern char *bmsToString(const struct Bitmapset *bms); |
| 616 | |
| 617 | /* |
| 618 | * nodes/{readfuncs.c,read.c} |
| 619 | */ |
| 620 | extern void *stringToNode(const char *str); |
| 621 | #ifdef WRITE_READ_PARSE_PLAN_TREES |
| 622 | extern void *stringToNodeWithLocations(const char *str); |
| 623 | #endif |
| 624 | extern struct Bitmapset *readBitmapset(void); |
| 625 | extern uintptr_t readDatum(bool typbyval); |
| 626 | extern bool *readBoolCols(int numCols); |
| 627 | extern int *readIntCols(int numCols); |
| 628 | extern Oid *readOidCols(int numCols); |
| 629 | extern int16 *readAttrNumberCols(int numCols); |
| 630 | |
| 631 | /* |
| 632 | * nodes/copyfuncs.c |
| 633 | */ |
| 634 | extern void *copyObjectImpl(const void *obj); |
| 635 | |
| 636 | /* cast result back to argument type, if supported by compiler */ |
| 637 | #ifdef HAVE_TYPEOF |
| 638 | #define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj)) |
| 639 | #else |
| 640 | #define copyObject(obj) copyObjectImpl(obj) |
| 641 | #endif |
| 642 | |
| 643 | /* |
| 644 | * nodes/equalfuncs.c |
| 645 | */ |
| 646 | extern bool equal(const void *a, const void *b); |
| 647 | |
| 648 | |
| 649 | /* |
| 650 | * Typedefs for identifying qualifier selectivities and plan costs as such. |
| 651 | * These are just plain "double"s, but declaring a variable as Selectivity |
| 652 | * or Cost makes the intent more obvious. |
| 653 | * |
| 654 | * These could have gone into plannodes.h or some such, but many files |
| 655 | * depend on them... |
| 656 | */ |
| 657 | typedef double Selectivity; /* fraction of tuples a qualifier will pass */ |
| 658 | typedef double Cost; /* execution cost (in page-access units) */ |
| 659 | |
| 660 | |
| 661 | /* |
| 662 | * CmdType - |
| 663 | * enums for type of operation represented by a Query or PlannedStmt |
| 664 | * |
| 665 | * This is needed in both parsenodes.h and plannodes.h, so put it here... |
| 666 | */ |
| 667 | typedef enum CmdType |
| 668 | { |
| 669 | CMD_UNKNOWN, |
| 670 | CMD_SELECT, /* select stmt */ |
| 671 | CMD_UPDATE, /* update stmt */ |
| 672 | CMD_INSERT, /* insert stmt */ |
| 673 | CMD_DELETE, |
| 674 | CMD_UTILITY, /* cmds like create, destroy, copy, vacuum, |
| 675 | * etc. */ |
| 676 | CMD_NOTHING /* dummy command for instead nothing rules |
| 677 | * with qual */ |
| 678 | } CmdType; |
| 679 | |
| 680 | |
| 681 | /* |
| 682 | * JoinType - |
| 683 | * enums for types of relation joins |
| 684 | * |
| 685 | * JoinType determines the exact semantics of joining two relations using |
| 686 | * a matching qualification. For example, it tells what to do with a tuple |
| 687 | * that has no match in the other relation. |
| 688 | * |
| 689 | * This is needed in both parsenodes.h and plannodes.h, so put it here... |
| 690 | */ |
| 691 | typedef enum JoinType |
| 692 | { |
| 693 | /* |
| 694 | * The canonical kinds of joins according to the SQL JOIN syntax. Only |
| 695 | * these codes can appear in parser output (e.g., JoinExpr nodes). |
| 696 | */ |
| 697 | JOIN_INNER, /* matching tuple pairs only */ |
| 698 | JOIN_LEFT, /* pairs + unmatched LHS tuples */ |
| 699 | JOIN_FULL, /* pairs + unmatched LHS + unmatched RHS */ |
| 700 | JOIN_RIGHT, /* pairs + unmatched RHS tuples */ |
| 701 | |
| 702 | /* |
| 703 | * Semijoins and anti-semijoins (as defined in relational theory) do not |
| 704 | * appear in the SQL JOIN syntax, but there are standard idioms for |
| 705 | * representing them (e.g., using EXISTS). The planner recognizes these |
| 706 | * cases and converts them to joins. So the planner and executor must |
| 707 | * support these codes. NOTE: in JOIN_SEMI output, it is unspecified |
| 708 | * which matching RHS row is joined to. In JOIN_ANTI output, the row is |
| 709 | * guaranteed to be null-extended. |
| 710 | */ |
| 711 | JOIN_SEMI, /* 1 copy of each LHS row that has match(es) */ |
| 712 | JOIN_ANTI, /* 1 copy of each LHS row that has no match */ |
| 713 | |
| 714 | /* |
| 715 | * These codes are used internally in the planner, but are not supported |
| 716 | * by the executor (nor, indeed, by most of the planner). |
| 717 | */ |
| 718 | JOIN_UNIQUE_OUTER, /* LHS path must be made unique */ |
| 719 | JOIN_UNIQUE_INNER /* RHS path must be made unique */ |
| 720 | |
| 721 | /* |
| 722 | * We might need additional join types someday. |
| 723 | */ |
| 724 | } JoinType; |
| 725 | |
| 726 | /* |
| 727 | * OUTER joins are those for which pushed-down quals must behave differently |
| 728 | * from the join's own quals. This is in fact everything except INNER and |
| 729 | * SEMI joins. However, this macro must also exclude the JOIN_UNIQUE symbols |
| 730 | * since those are temporary proxies for what will eventually be an INNER |
| 731 | * join. |
| 732 | * |
| 733 | * Note: semijoins are a hybrid case, but we choose to treat them as not |
| 734 | * being outer joins. This is okay principally because the SQL syntax makes |
| 735 | * it impossible to have a pushed-down qual that refers to the inner relation |
| 736 | * of a semijoin; so there is no strong need to distinguish join quals from |
| 737 | * pushed-down quals. This is convenient because for almost all purposes, |
| 738 | * quals attached to a semijoin can be treated the same as innerjoin quals. |
| 739 | */ |
| 740 | #define IS_OUTER_JOIN(jointype) \ |
| 741 | (((1 << (jointype)) & \ |
| 742 | ((1 << JOIN_LEFT) | \ |
| 743 | (1 << JOIN_FULL) | \ |
| 744 | (1 << JOIN_RIGHT) | \ |
| 745 | (1 << JOIN_ANTI))) != 0) |
| 746 | |
| 747 | /* |
| 748 | * AggStrategy - |
| 749 | * overall execution strategies for Agg plan nodes |
| 750 | * |
| 751 | * This is needed in both pathnodes.h and plannodes.h, so put it here... |
| 752 | */ |
| 753 | typedef enum AggStrategy |
| 754 | { |
| 755 | AGG_PLAIN, /* simple agg across all input rows */ |
| 756 | AGG_SORTED, /* grouped agg, input must be sorted */ |
| 757 | AGG_HASHED, /* grouped agg, use internal hashtable */ |
| 758 | AGG_MIXED /* grouped agg, hash and sort both used */ |
| 759 | } AggStrategy; |
| 760 | |
| 761 | /* |
| 762 | * AggSplit - |
| 763 | * splitting (partial aggregation) modes for Agg plan nodes |
| 764 | * |
| 765 | * This is needed in both pathnodes.h and plannodes.h, so put it here... |
| 766 | */ |
| 767 | |
| 768 | /* Primitive options supported by nodeAgg.c: */ |
| 769 | #define AGGSPLITOP_COMBINE 0x01 /* substitute combinefn for transfn */ |
| 770 | #define AGGSPLITOP_SKIPFINAL 0x02 /* skip finalfn, return state as-is */ |
| 771 | #define AGGSPLITOP_SERIALIZE 0x04 /* apply serializefn to output */ |
| 772 | #define AGGSPLITOP_DESERIALIZE 0x08 /* apply deserializefn to input */ |
| 773 | |
| 774 | /* Supported operating modes (i.e., useful combinations of these options): */ |
| 775 | typedef enum AggSplit |
| 776 | { |
| 777 | /* Basic, non-split aggregation: */ |
| 778 | AGGSPLIT_SIMPLE = 0, |
| 779 | /* Initial phase of partial aggregation, with serialization: */ |
| 780 | AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE, |
| 781 | /* Final phase of partial aggregation, with deserialization: */ |
| 782 | AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE |
| 783 | } AggSplit; |
| 784 | |
| 785 | /* Test whether an AggSplit value selects each primitive option: */ |
| 786 | #define DO_AGGSPLIT_COMBINE(as) (((as) & AGGSPLITOP_COMBINE) != 0) |
| 787 | #define DO_AGGSPLIT_SKIPFINAL(as) (((as) & AGGSPLITOP_SKIPFINAL) != 0) |
| 788 | #define DO_AGGSPLIT_SERIALIZE(as) (((as) & AGGSPLITOP_SERIALIZE) != 0) |
| 789 | #define DO_AGGSPLIT_DESERIALIZE(as) (((as) & AGGSPLITOP_DESERIALIZE) != 0) |
| 790 | |
| 791 | /* |
| 792 | * SetOpCmd and SetOpStrategy - |
| 793 | * overall semantics and execution strategies for SetOp plan nodes |
| 794 | * |
| 795 | * This is needed in both pathnodes.h and plannodes.h, so put it here... |
| 796 | */ |
| 797 | typedef enum SetOpCmd |
| 798 | { |
| 799 | SETOPCMD_INTERSECT, |
| 800 | SETOPCMD_INTERSECT_ALL, |
| 801 | SETOPCMD_EXCEPT, |
| 802 | SETOPCMD_EXCEPT_ALL |
| 803 | } SetOpCmd; |
| 804 | |
| 805 | typedef enum SetOpStrategy |
| 806 | { |
| 807 | SETOP_SORTED, /* input must be sorted */ |
| 808 | SETOP_HASHED /* use internal hashtable */ |
| 809 | } SetOpStrategy; |
| 810 | |
| 811 | /* |
| 812 | * OnConflictAction - |
| 813 | * "ON CONFLICT" clause type of query |
| 814 | * |
| 815 | * This is needed in both parsenodes.h and plannodes.h, so put it here... |
| 816 | */ |
| 817 | typedef enum OnConflictAction |
| 818 | { |
| 819 | ONCONFLICT_NONE, /* No "ON CONFLICT" clause */ |
| 820 | ONCONFLICT_NOTHING, /* ON CONFLICT ... DO NOTHING */ |
| 821 | ONCONFLICT_UPDATE /* ON CONFLICT ... DO UPDATE */ |
| 822 | } OnConflictAction; |
| 823 | |
| 824 | #endif /* NODES_H */ |
| 825 | |