| Line | Hits | Source | Commit |
| 1094 |
- |
ProcessUtilitySlow(ParseState *pstate, |
- |
| 1095 |
- |
PlannedStmt *pstmt, |
- |
| 1096 |
- |
const char *queryString, |
- |
| 1097 |
- |
ProcessUtilityContext context, |
- |
| 1098 |
- |
ParamListInfo params, |
- |
| 1099 |
- |
QueryEnvironment *queryEnv, |
- |
| 1100 |
- |
DestReceiver *dest, |
- |
| 1101 |
- |
QueryCompletion *qc) |
- |
| 1102 |
- |
{ |
- |
| 1103 |
- |
Node *parsetree = pstmt->utilityStmt; |
- |
| 1104 |
- |
bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL); |
- |
| 1105 |
- |
bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); |
- |
| 1106 |
- |
bool needCleanup; |
- |
| 1107 |
- |
bool commandCollected = false; |
- |
| 1108 |
- |
ObjectAddress address; |
- |
| 1109 |
- |
ObjectAddress secondaryObject = InvalidObjectAddress; |
- |
| 1110 |
- |
|
- |
| 1111 |
- |
/* All event trigger calls are done only when isCompleteQuery is true */ |
- |
| 1112 |
- |
needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); |
- |
| 1113 |
- |
|
- |
| 1114 |
- |
/* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */ |
- |
| 1115 |
- |
PG_TRY(); |
- |
| 1116 |
- |
{ |
- |
| 1117 |
- |
if (isCompleteQuery) |
- |
| 1118 |
- |
EventTriggerDDLCommandStart(parsetree); |
- |
| 1119 |
- |
|
- |
| 1120 |
- |
switch (nodeTag(parsetree)) |
- |
| 1121 |
- |
{ |
- |
| 1122 |
- |
/* |
- |
| 1123 |
- |
* relation and attribute manipulation |
- |
| 1124 |
- |
*/ |
- |
| 1125 |
- |
case T_CreateSchemaStmt: |
- |
| 1126 |
- |
CreateSchemaCommand(pstate, |
- |
| 1127 |
- |
(CreateSchemaStmt *) parsetree, |
- |
| 1128 |
- |
pstmt->stmt_location, |
- |
| 1129 |
- |
pstmt->stmt_len); |
- |
| 1130 |
- |
|
- |
| 1131 |
- |
/* |
- |
| 1132 |
- |
* EventTriggerCollectSimpleCommand called by |
- |
| 1133 |
- |
* CreateSchemaCommand |
- |
| 1134 |
- |
*/ |
- |
| 1135 |
- |
commandCollected = true; |
- |
| 1136 |
- |
break; |
- |
| 1137 |
- |
|
- |
| 1138 |
- |
case T_CreateStmt: |
- |
| 1139 |
- |
case T_CreateForeignTableStmt: |
- |
| 1140 |
- |
{ |
- |
| 1141 |
- |
List *stmts; |
- |
| 1142 |
- |
RangeVar *table_rv = NULL; |
- |
| 1143 |
- |
|
- |
| 1144 |
- |
/* Run parse analysis ... */ |
- |
| 1145 |
- |
stmts = transformCreateStmt((CreateStmt *) parsetree, |
- |
| 1146 |
- |
queryString); |
- |
| 1147 |
- |
|
- |
| 1148 |
- |
/* |
- |
| 1149 |
- |
* ... and do it. We can't use foreach() because we may |
- |
| 1150 |
- |
* modify the list midway through, so pick off the |
- |
| 1151 |
- |
* elements one at a time, the hard way. |
- |
| 1152 |
- |
*/ |
- |
| 1153 |
- |
while (stmts != NIL) |
- |
| 1154 |
- |
{ |
- |
| 1155 |
- |
Node *stmt = (Node *) linitial(stmts); |
- |
| 1156 |
- |
|
- |
| 1157 |
- |
stmts = list_delete_first(stmts); |
- |
| 1158 |
- |
|
- |
| 1159 |
- |
if (IsA(stmt, CreateStmt)) |
- |
| 1160 |
- |
{ |
- |
| 1161 |
- |
CreateStmt *cstmt = (CreateStmt *) stmt; |
- |
| 1162 |
- |
Datum toast_options; |
- |
| 1163 |
- |
const char *const validnsps[] = HEAP_RELOPT_NAMESPACES; |
- |
| 1164 |
- |
|
- |
| 1165 |
- |
/* Remember transformed RangeVar for LIKE */ |
- |
| 1166 |
- |
table_rv = cstmt->relation; |
- |
| 1167 |
- |
|
- |
| 1168 |
- |
/* Create the table itself */ |
- |
| 1169 |
- |
address = DefineRelation(cstmt, |
- |
| 1170 |
- |
RELKIND_RELATION, |
- |
| 1171 |
- |
InvalidOid, NULL, |
- |
| 1172 |
- |
queryString); |
- |
| 1173 |
- |
EventTriggerCollectSimpleCommand(address, |
- |
| 1174 |
- |
secondaryObject, |
- |
| 1175 |
- |
stmt); |
- |
| 1176 |
- |
|
- |
| 1177 |
- |
/* |
- |
| 1178 |
- |
* Let NewRelationCreateToastTable decide if this |
- |
| 1179 |
- |
* one needs a secondary relation too. |
- |
| 1180 |
- |
*/ |
- |
| 1181 |
- |
CommandCounterIncrement(); |
- |
| 1182 |
- |
|
- |
| 1183 |
- |
/* |
- |
| 1184 |
- |
* parse and validate reloptions for the toast |
- |
| 1185 |
- |
* table |
- |
| 1186 |
- |
*/ |
- |
| 1187 |
- |
toast_options = transformRelOptions((Datum) 0, |
- |
| 1188 |
- |
cstmt->options, |
- |
| 1189 |
- |
"toast", |
- |
| 1190 |
- |
validnsps, |
- |
| 1191 |
- |
true, |
- |
| 1192 |
- |
false); |
- |
| 1193 |
- |
(void) heap_reloptions(RELKIND_TOASTVALUE, |
- |
| 1194 |
- |
toast_options, |
- |
| 1195 |
- |
true); |
- |
| 1196 |
- |
|
- |
| 1197 |
- |
NewRelationCreateToastTable(address.objectId, |
- |
| 1198 |
- |
toast_options); |
- |
| 1199 |
- |
} |
- |
| 1200 |
- |
else if (IsA(stmt, CreateForeignTableStmt)) |
- |
| 1201 |
- |
{ |
- |
| 1202 |
- |
CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt; |
- |
| 1203 |
- |
|
- |
| 1204 |
- |
/* Remember transformed RangeVar for LIKE */ |
- |
| 1205 |
- |
table_rv = cstmt->base.relation; |
- |
| 1206 |
- |
|
- |
| 1207 |
- |
/* Create the table itself */ |
- |
| 1208 |
- |
address = DefineRelation(&cstmt->base, |
- |
| 1209 |
- |
RELKIND_FOREIGN_TABLE, |
- |
| 1210 |
- |
InvalidOid, NULL, |
- |
| 1211 |
- |
queryString); |
- |
| 1212 |
- |
CreateForeignTable(cstmt, |
- |
| 1213 |
- |
address.objectId); |
- |
| 1214 |
- |
EventTriggerCollectSimpleCommand(address, |
- |
| 1215 |
- |
secondaryObject, |
- |
| 1216 |
- |
stmt); |
- |
| 1217 |
- |
} |
- |
| 1218 |
- |
else if (IsA(stmt, TableLikeClause)) |
- |
| 1219 |
- |
{ |
- |
| 1220 |
- |
/* |
- |
| 1221 |
- |
* Do delayed processing of LIKE options. This |
- |
| 1222 |
- |
* will result in additional sub-statements for us |
- |
| 1223 |
- |
* to process. Those should get done before any |
- |
| 1224 |
- |
* remaining actions, so prepend them to "stmts". |
- |
| 1225 |
- |
*/ |
- |
| 1226 |
- |
TableLikeClause *like = (TableLikeClause *) stmt; |
- |
| 1227 |
- |
List *morestmts; |
- |
| 1228 |
- |
|
- |
| 1229 |
- |
Assert(table_rv != NULL); |
- |
| 1230 |
- |
|
- |
| 1231 |
- |
morestmts = expandTableLikeClause(table_rv, like); |
- |
| 1232 |
- |
stmts = list_concat(morestmts, stmts); |
- |
| 1233 |
- |
} |
- |
| 1234 |
- |
else |
- |
| 1235 |
- |
{ |
- |
| 1236 |
- |
/* |
- |
| 1237 |
- |
* Recurse for anything else. Note the recursive |
- |
| 1238 |
- |
* call will stash the objects so created into our |
- |
| 1239 |
- |
* event trigger context. |
- |
| 1240 |
- |
*/ |
- |
| 1241 |
- |
PlannedStmt *wrapper; |
- |
| 1242 |
- |
|
- |
| 1243 |
- |
wrapper = makeNode(PlannedStmt); |
- |
| 1244 |
- |
wrapper->commandType = CMD_UTILITY; |
- |
| 1245 |
- |
wrapper->canSetTag = false; |
- |
| 1246 |
- |
wrapper->utilityStmt = stmt; |
- |
| 1247 |
- |
wrapper->stmt_location = pstmt->stmt_location; |
- |
| 1248 |
- |
wrapper->stmt_len = pstmt->stmt_len; |
- |
| 1249 |
- |
wrapper->planOrigin = PLAN_STMT_INTERNAL; |
- |
| 1250 |
- |
|
- |
| 1251 |
- |
ProcessUtility(wrapper, |
- |
| 1252 |
- |
queryString, |
- |
| 1253 |
- |
false, |
- |
| 1254 |
- |
PROCESS_UTILITY_SUBCOMMAND, |
- |
| 1255 |
- |
params, |
- |
| 1256 |
- |
NULL, |
- |
| 1257 |
- |
None_Receiver, |
- |
| 1258 |
- |
NULL); |
- |
| 1259 |
- |
} |
- |
| 1260 |
- |
|
- |
| 1261 |
- |
/* Need CCI between commands */ |
- |
| 1262 |
- |
if (stmts != NIL) |
- |
| 1263 |
- |
CommandCounterIncrement(); |
- |
| 1264 |
- |
} |
- |
| 1265 |
- |
|
- |
| 1266 |
- |
/* |
- |
| 1267 |
- |
* The multiple commands generated here are stashed |
- |
| 1268 |
- |
* individually, so disable collection below. |
- |
| 1269 |
- |
*/ |
- |
| 1270 |
- |
commandCollected = true; |
- |
| 1271 |
- |
} |
- |
| 1272 |
- |
break; |
- |
| 1273 |
- |
|
- |
| 1274 |
- |
case T_AlterTableStmt: |
- |
| 1275 |
- |
{ |
- |
| 1276 |
- |
AlterTableStmt *atstmt = (AlterTableStmt *) parsetree; |
- |
| 1277 |
- |
Oid relid; |
- |
| 1278 |
- |
LOCKMODE lockmode; |
- |
| 1279 |
- |
ListCell *cell; |
- |
| 1280 |
- |
|
- |
| 1281 |
- |
/* |
- |
| 1282 |
- |
* Disallow ALTER TABLE .. DETACH CONCURRENTLY in a |
- |
| 1283 |
- |
* transaction block or function. (Perhaps it could be |
- |
| 1284 |
- |
* allowed in a procedure, but don't hold your breath.) |
- |
| 1285 |
- |
*/ |
- |
| 1286 |
- |
foreach(cell, atstmt->cmds) |
- |
| 1287 |
- |
{ |
- |
| 1288 |
- |
AlterTableCmd *cmd = (AlterTableCmd *) lfirst(cell); |
- |
| 1289 |
- |
|
- |
| 1290 |
- |
/* Disallow DETACH CONCURRENTLY in a transaction block */ |
- |
| 1291 |
- |
if (cmd->subtype == AT_DetachPartition) |
- |
| 1292 |
- |
{ |
- |
| 1293 |
- |
if (((PartitionCmd *) cmd->def)->concurrent) |
- |
| 1294 |
- |
PreventInTransactionBlock(isTopLevel, |
- |
| 1295 |
- |
"ALTER TABLE ... DETACH CONCURRENTLY"); |
- |
| 1296 |
- |
} |
- |
| 1297 |
- |
} |
- |
| 1298 |
- |
|
- |
| 1299 |
- |
/* |
- |
| 1300 |
- |
* Figure out lock mode, and acquire lock. This also does |
- |
| 1301 |
- |
* basic permissions checks, so that we won't wait for a |
- |
| 1302 |
- |
* lock on (for example) a relation on which we have no |
- |
| 1303 |
- |
* permissions. |
- |
| 1304 |
- |
*/ |
- |
| 1305 |
- |
lockmode = AlterTableGetLockLevel(atstmt->cmds); |
- |
| 1306 |
- |
relid = AlterTableLookupRelation(atstmt, lockmode); |
- |
| 1307 |
- |
|
- |
| 1308 |
- |
if (OidIsValid(relid)) |
- |
| 1309 |
- |
{ |
- |
| 1310 |
- |
AlterTableUtilityContext atcontext; |
- |
| 1311 |
- |
|
- |
| 1312 |
- |
/* Set up info needed for recursive callbacks ... */ |
- |
| 1313 |
- |
atcontext.pstmt = pstmt; |
- |
| 1314 |
- |
atcontext.queryString = queryString; |
- |
| 1315 |
- |
atcontext.relid = relid; |
- |
| 1316 |
- |
atcontext.params = params; |
- |
| 1317 |
- |
atcontext.queryEnv = queryEnv; |
- |
| 1318 |
- |
|
- |
| 1319 |
- |
/* ... ensure we have an event trigger context ... */ |
- |
| 1320 |
- |
EventTriggerAlterTableStart(parsetree); |
- |
| 1321 |
- |
EventTriggerAlterTableRelid(relid); |
- |
| 1322 |
- |
|
- |
| 1323 |
- |
/* ... and do it */ |
- |
| 1324 |
- |
AlterTable(atstmt, lockmode, &atcontext); |
- |
| 1325 |
- |
|
- |
| 1326 |
- |
/* done */ |
- |
| 1327 |
- |
EventTriggerAlterTableEnd(); |
- |
| 1328 |
- |
} |
- |
| 1329 |
- |
else |
- |
| 1330 |
- |
ereport(NOTICE, |
- |
| 1331 |
- |
(errmsg("relation \"%s\" does not exist, skipping", |
- |
| 1332 |
- |
atstmt->relation->relname))); |
- |
| 1333 |
- |
} |
- |
| 1334 |
- |
|
- |
| 1335 |
- |
/* ALTER TABLE stashes commands internally */ |
- |
| 1336 |
- |
commandCollected = true; |
- |
| 1337 |
- |
break; |
- |
| 1338 |
- |
|
- |
| 1339 |
- |
case T_AlterDomainStmt: |
- |
| 1340 |
- |
{ |
- |
| 1341 |
- |
AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree; |
- |
| 1342 |
- |
|
- |
| 1343 |
- |
/* |
- |
| 1344 |
- |
* Some or all of these functions are recursive to cover |
- |
| 1345 |
- |
* inherited things, so permission checks are done there. |
- |
| 1346 |
- |
*/ |
- |
| 1347 |
- |
switch (stmt->subtype) |
- |
| 1348 |
- |
{ |
- |
| 1349 |
- |
case AD_AlterDefault: |
- |
| 1350 |
- |
|
- |
| 1351 |
- |
/* |
- |
| 1352 |
- |
* Recursively alter column default for table and, |
- |
| 1353 |
- |
* if requested, for descendants |
- |
| 1354 |
- |
*/ |
- |
| 1355 |
- |
address = |
- |
| 1356 |
- |
AlterDomainDefault(stmt->typeName, |
- |
| 1357 |
- |
stmt->def); |
- |
| 1358 |
- |
break; |
- |
| 1359 |
- |
case AD_DropNotNull: |
- |
| 1360 |
- |
address = |
- |
| 1361 |
- |
AlterDomainNotNull(stmt->typeName, |
- |
| 1362 |
- |
false); |
- |
| 1363 |
- |
break; |
- |
| 1364 |
- |
case AD_SetNotNull: |
- |
| 1365 |
- |
address = |
- |
| 1366 |
- |
AlterDomainNotNull(stmt->typeName, |
- |
| 1367 |
- |
true); |
- |
| 1368 |
- |
break; |
- |
| 1369 |
- |
case AD_AddConstraint: |
- |
| 1370 |
- |
address = |
- |
| 1371 |
- |
AlterDomainAddConstraint(stmt->typeName, |
- |
| 1372 |
- |
stmt->def, |
- |
| 1373 |
- |
&secondaryObject); |
- |
| 1374 |
- |
break; |
- |
| 1375 |
- |
case AD_DropConstraint: |
- |
| 1376 |
- |
address = |
- |
| 1377 |
- |
AlterDomainDropConstraint(stmt->typeName, |
- |
| 1378 |
- |
stmt->name, |
- |
| 1379 |
- |
stmt->behavior, |
- |
| 1380 |
- |
stmt->missing_ok); |
- |
| 1381 |
- |
break; |
- |
| 1382 |
- |
case AD_ValidateConstraint: |
- |
| 1383 |
- |
address = |
- |
| 1384 |
- |
AlterDomainValidateConstraint(stmt->typeName, |
- |
| 1385 |
- |
stmt->name); |
- |
| 1386 |
- |
break; |
- |
| 1387 |
- |
default: /* oops */ |
- |
| 1388 |
- |
elog(ERROR, "unrecognized alter domain type: %d", |
- |
| 1389 |
- |
(int) stmt->subtype); |
- |
| 1390 |
- |
break; |
- |
| 1391 |
- |
} |
- |
| 1392 |
- |
} |
- |
| 1393 |
- |
break; |
- |
| 1394 |
- |
|
- |
| 1395 |
- |
/* |
- |
| 1396 |
- |
* ************* object creation / destruction ************** |
- |
| 1397 |
- |
*/ |
- |
| 1398 |
- |
case T_DefineStmt: |
- |
| 1399 |
- |
{ |
- |
| 1400 |
- |
DefineStmt *stmt = (DefineStmt *) parsetree; |
- |
| 1401 |
- |
|
- |
| 1402 |
- |
switch (stmt->kind) |
- |
| 1403 |
- |
{ |
- |
| 1404 |
- |
case OBJECT_AGGREGATE: |
- |
| 1405 |
- |
address = |
- |
| 1406 |
- |
DefineAggregate(pstate, stmt->defnames, stmt->args, |
- |
| 1407 |
- |
stmt->oldstyle, |
- |
| 1408 |
- |
stmt->definition, |
- |
| 1409 |
- |
stmt->replace); |
- |
| 1410 |
- |
break; |
- |
| 1411 |
- |
case OBJECT_OPERATOR: |
- |
| 1412 |
- |
Assert(stmt->args == NIL); |
- |
| 1413 |
- |
address = DefineOperator(stmt->defnames, |
- |
| 1414 |
- |
stmt->definition); |
- |
| 1415 |
- |
break; |
- |
| 1416 |
- |
case OBJECT_TYPE: |
- |
| 1417 |
- |
Assert(stmt->args == NIL); |
- |
| 1418 |
- |
address = DefineType(pstate, |
- |
| 1419 |
- |
stmt->defnames, |
- |
| 1420 |
- |
stmt->definition); |
- |
| 1421 |
- |
break; |
- |
| 1422 |
- |
case OBJECT_TSPARSER: |
- |
| 1423 |
- |
Assert(stmt->args == NIL); |
- |
| 1424 |
- |
address = DefineTSParser(stmt->defnames, |
- |
| 1425 |
- |
stmt->definition); |
- |
| 1426 |
- |
break; |
- |
| 1427 |
- |
case OBJECT_TSDICTIONARY: |
- |
| 1428 |
- |
Assert(stmt->args == NIL); |
- |
| 1429 |
- |
address = DefineTSDictionary(stmt->defnames, |
- |
| 1430 |
- |
stmt->definition); |
- |
| 1431 |
- |
break; |
- |
| 1432 |
- |
case OBJECT_TSTEMPLATE: |
- |
| 1433 |
- |
Assert(stmt->args == NIL); |
- |
| 1434 |
- |
address = DefineTSTemplate(stmt->defnames, |
- |
| 1435 |
- |
stmt->definition); |
- |
| 1436 |
- |
break; |
- |
| 1437 |
- |
case OBJECT_TSCONFIGURATION: |
- |
| 1438 |
- |
Assert(stmt->args == NIL); |
- |
| 1439 |
- |
address = DefineTSConfiguration(stmt->defnames, |
- |
| 1440 |
- |
stmt->definition, |
- |
| 1441 |
- |
&secondaryObject); |
- |
| 1442 |
- |
break; |
- |
| 1443 |
- |
case OBJECT_COLLATION: |
- |
| 1444 |
- |
Assert(stmt->args == NIL); |
- |
| 1445 |
- |
address = DefineCollation(pstate, |
- |
| 1446 |
- |
stmt->defnames, |
- |
| 1447 |
- |
stmt->definition, |
- |
| 1448 |
- |
stmt->if_not_exists); |
- |
| 1449 |
- |
break; |
- |
| 1450 |
- |
default: |
- |
| 1451 |
- |
elog(ERROR, "unrecognized define stmt type: %d", |
- |
| 1452 |
- |
(int) stmt->kind); |
- |
| 1453 |
- |
break; |
- |
| 1454 |
- |
} |
- |
| 1455 |
- |
} |
- |
| 1456 |
- |
break; |
- |
| 1457 |
- |
|
- |
| 1458 |
- |
case T_IndexStmt: /* CREATE INDEX */ |
- |
| 1459 |
- |
{ |
- |
| 1460 |
- |
IndexStmt *stmt = (IndexStmt *) parsetree; |
- |
| 1461 |
- |
Oid relid; |
- |
| 1462 |
- |
LOCKMODE lockmode; |
- |
| 1463 |
- |
int nparts = -1; |
- |
| 1464 |
- |
bool is_alter_table; |
- |
| 1465 |
- |
|
- |
| 1466 |
- |
if (stmt->concurrent) |
- |
| 1467 |
- |
PreventInTransactionBlock(isTopLevel, |
- |
| 1468 |
- |
"CREATE INDEX CONCURRENTLY"); |
- |
| 1469 |
- |
|
- |
| 1470 |
- |
/* |
- |
| 1471 |
- |
* Look up the relation OID just once, right here at the |
- |
| 1472 |
- |
* beginning, so that we don't end up repeating the name |
- |
| 1473 |
- |
* lookup later and latching onto a different relation |
- |
| 1474 |
- |
* partway through. To avoid lock upgrade hazards, it's |
- |
| 1475 |
- |
* important that we take the strongest lock that will |
- |
| 1476 |
- |
* eventually be needed here, so the lockmode calculation |
- |
| 1477 |
- |
* needs to match what DefineIndex() does. |
- |
| 1478 |
- |
*/ |
- |
| 1479 |
- |
lockmode = stmt->concurrent ? ShareUpdateExclusiveLock |
- |
| 1480 |
- |
: ShareLock; |
- |
| 1481 |
- |
relid = |
- |
| 1482 |
- |
RangeVarGetRelidExtended(stmt->relation, lockmode, |
- |
| 1483 |
- |
0, |
- |
| 1484 |
- |
RangeVarCallbackOwnsRelation, |
- |
| 1485 |
- |
NULL); |
- |
| 1486 |
- |
|
- |
| 1487 |
- |
/* |
- |
| 1488 |
- |
* CREATE INDEX on partitioned tables (but not regular |
- |
| 1489 |
- |
* inherited tables) recurses to partitions, so we must |
- |
| 1490 |
- |
* acquire locks early to avoid deadlocks. |
- |
| 1491 |
- |
* |
- |
| 1492 |
- |
* We also take the opportunity to verify that all |
- |
| 1493 |
- |
* partitions are something we can put an index on, to |
- |
| 1494 |
- |
* avoid building some indexes only to fail later. While |
- |
| 1495 |
- |
* at it, also count the partitions, so that DefineIndex |
- |
| 1496 |
- |
* needn't do a duplicative find_all_inheritors search. |
- |
| 1497 |
- |
*/ |
- |
| 1498 |
- |
if (stmt->relation->inh && |
- |
| 1499 |
- |
get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE) |
- |
| 1500 |
- |
{ |
- |
| 1501 |
- |
ListCell *lc; |
- |
| 1502 |
- |
List *inheritors = NIL; |
- |
| 1503 |
- |
|
- |
| 1504 |
- |
inheritors = find_all_inheritors(relid, lockmode, NULL); |
- |
| 1505 |
- |
foreach(lc, inheritors) |
- |
| 1506 |
- |
{ |
- |
| 1507 |
- |
Oid partrelid = lfirst_oid(lc); |
- |
| 1508 |
- |
char relkind = get_rel_relkind(partrelid); |
- |
| 1509 |
- |
|
- |
| 1510 |
- |
if (relkind != RELKIND_RELATION && |
- |
| 1511 |
- |
relkind != RELKIND_MATVIEW && |
- |
| 1512 |
- |
relkind != RELKIND_PARTITIONED_TABLE && |
- |
| 1513 |
- |
relkind != RELKIND_FOREIGN_TABLE) |
- |
| 1514 |
- |
elog(ERROR, "unexpected relkind \"%c\" on partition \"%s\"", |
- |
| 1515 |
- |
relkind, stmt->relation->relname); |
- |
| 1516 |
- |
|
- |
| 1517 |
- |
if (relkind == RELKIND_FOREIGN_TABLE && |
- |
| 1518 |
- |
(stmt->unique || stmt->primary)) |
- |
| 1519 |
- |
ereport(ERROR, |
- |
| 1520 |
- |
(errcode(ERRCODE_WRONG_OBJECT_TYPE), |
- |
| 1521 |
- |
errmsg("cannot create unique index on partitioned table \"%s\"", |
- |
| 1522 |
- |
stmt->relation->relname), |
- |
| 1523 |
- |
errdetail("Table \"%s\" contains partitions that are foreign tables.", |
- |
| 1524 |
- |
stmt->relation->relname))); |
- |
| 1525 |
- |
} |
- |
| 1526 |
- |
/* count direct and indirect children, but not rel */ |
- |
| 1527 |
- |
nparts = list_length(inheritors) - 1; |
- |
| 1528 |
- |
list_free(inheritors); |
- |
| 1529 |
- |
} |
- |
| 1530 |
- |
|
- |
| 1531 |
- |
/* |
- |
| 1532 |
- |
* If the IndexStmt is already transformed, it must have |
- |
| 1533 |
- |
* come from generateClonedIndexStmt, which in current |
- |
| 1534 |
- |
* usage means it came from expandTableLikeClause rather |
- |
| 1535 |
- |
* than from original parse analysis. And that means we |
- |
| 1536 |
- |
* must treat it like ALTER TABLE ADD INDEX, not CREATE. |
- |
| 1537 |
- |
* (This is a bit grotty, but currently it doesn't seem |
- |
| 1538 |
- |
* worth adding a separate bool field for the purpose.) |
- |
| 1539 |
- |
*/ |
- |
| 1540 |
- |
is_alter_table = stmt->transformed; |
- |
| 1541 |
- |
|
- |
| 1542 |
- |
/* Run parse analysis ... */ |
- |
| 1543 |
- |
stmt = transformIndexStmt(relid, stmt, queryString); |
- |
| 1544 |
- |
|
- |
| 1545 |
- |
/* ... and do it */ |
- |
| 1546 |
- |
EventTriggerAlterTableStart(parsetree); |
- |
| 1547 |
- |
address = |
- |
| 1548 |
- |
DefineIndex(pstate, |
- |
| 1549 |
- |
relid, /* OID of heap relation */ |
- |
| 1550 |
- |
stmt, |
- |
| 1551 |
- |
InvalidOid, /* no predefined OID */ |
- |
| 1552 |
- |
InvalidOid, /* no parent index */ |
- |
| 1553 |
- |
InvalidOid, /* no parent constraint */ |
- |
| 1554 |
- |
nparts, /* # of partitions, or -1 */ |
- |
| 1555 |
- |
is_alter_table, |
- |
| 1556 |
- |
true, /* check_rights */ |
- |
| 1557 |
- |
true, /* check_not_in_use */ |
- |
| 1558 |
- |
false, /* skip_build */ |
- |
| 1559 |
- |
false); /* quiet */ |
- |
| 1560 |
- |
|
- |
| 1561 |
- |
/* |
- |
| 1562 |
- |
* Add the CREATE INDEX node itself to stash right away; |
- |
| 1563 |
- |
* if there were any commands stashed in the ALTER TABLE |
- |
| 1564 |
- |
* code, we need them to appear after this one. |
- |
| 1565 |
- |
*/ |
- |
| 1566 |
- |
EventTriggerCollectSimpleCommand(address, secondaryObject, |
- |
| 1567 |
- |
parsetree); |
- |
| 1568 |
- |
commandCollected = true; |
- |
| 1569 |
- |
EventTriggerAlterTableEnd(); |
- |
| 1570 |
- |
} |
- |
| 1571 |
- |
break; |
- |
| 1572 |
- |
|
- |
| 1573 |
- |
case T_ReindexStmt: |
- |
| 1574 |
- |
ExecReindex(pstate, (ReindexStmt *) parsetree, isTopLevel); |
- |
| 1575 |
- |
|
- |
| 1576 |
- |
/* EventTriggerCollectSimpleCommand is called directly */ |
- |
| 1577 |
- |
commandCollected = true; |
- |
| 1578 |
- |
break; |
- |
| 1579 |
- |
|
- |
| 1580 |
- |
case T_CreateExtensionStmt: |
- |
| 1581 |
- |
address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree); |
- |
| 1582 |
- |
break; |
- |
| 1583 |
- |
|
- |
| 1584 |
- |
case T_AlterExtensionStmt: |
- |
| 1585 |
- |
address = ExecAlterExtensionStmt(pstate, (AlterExtensionStmt *) parsetree); |
- |
| 1586 |
- |
break; |
- |
| 1587 |
- |
|
- |
| 1588 |
- |
case T_AlterExtensionContentsStmt: |
- |
| 1589 |
- |
address = ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree, |
- |
| 1590 |
- |
&secondaryObject); |
- |
| 1591 |
- |
break; |
- |
| 1592 |
- |
|
- |
| 1593 |
- |
case T_CreateFdwStmt: |
- |
| 1594 |
- |
address = CreateForeignDataWrapper(pstate, (CreateFdwStmt *) parsetree); |
- |
| 1595 |
- |
break; |
- |
| 1596 |
- |
|
- |
| 1597 |
- |
case T_AlterFdwStmt: |
- |
| 1598 |
- |
address = AlterForeignDataWrapper(pstate, (AlterFdwStmt *) parsetree); |
- |
| 1599 |
- |
break; |
- |
| 1600 |
- |
|
- |
| 1601 |
- |
case T_CreateForeignServerStmt: |
- |
| 1602 |
- |
address = CreateForeignServer((CreateForeignServerStmt *) parsetree); |
- |
| 1603 |
- |
break; |
- |
| 1604 |
- |
|
- |
| 1605 |
- |
case T_AlterForeignServerStmt: |
- |
| 1606 |
- |
address = AlterForeignServer((AlterForeignServerStmt *) parsetree); |
- |
| 1607 |
- |
break; |
- |
| 1608 |
- |
|
- |
| 1609 |
- |
case T_CreateUserMappingStmt: |
- |
| 1610 |
- |
address = CreateUserMapping((CreateUserMappingStmt *) parsetree); |
- |
| 1611 |
- |
break; |
- |
| 1612 |
- |
|
- |
| 1613 |
- |
case T_AlterUserMappingStmt: |
- |
| 1614 |
- |
address = AlterUserMapping((AlterUserMappingStmt *) parsetree); |
- |
| 1615 |
- |
break; |
- |
| 1616 |
- |
|
- |
| 1617 |
- |
case T_DropUserMappingStmt: |
- |
| 1618 |
- |
RemoveUserMapping((DropUserMappingStmt *) parsetree); |
- |
| 1619 |
- |
/* no commands stashed for DROP */ |
- |
| 1620 |
- |
commandCollected = true; |
- |
| 1621 |
- |
break; |
- |
| 1622 |
- |
|
- |
| 1623 |
- |
case T_ImportForeignSchemaStmt: |
- |
| 1624 |
- |
ImportForeignSchema((ImportForeignSchemaStmt *) parsetree); |
- |
| 1625 |
- |
/* commands are stashed inside ImportForeignSchema */ |
- |
| 1626 |
- |
commandCollected = true; |
- |
| 1627 |
- |
break; |
- |
| 1628 |
- |
|
- |
| 1629 |
- |
case T_CompositeTypeStmt: /* CREATE TYPE (composite) */ |
- |
| 1630 |
- |
{ |
- |
| 1631 |
- |
CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree; |
- |
| 1632 |
- |
|
- |
| 1633 |
- |
address = DefineCompositeType(stmt->typevar, |
- |
| 1634 |
- |
stmt->coldeflist); |
- |
| 1635 |
- |
} |
- |
| 1636 |
- |
break; |
- |
| 1637 |
- |
|
- |
| 1638 |
- |
case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */ |
- |
| 1639 |
- |
address = DefineEnum((CreateEnumStmt *) parsetree); |
- |
| 1640 |
- |
break; |
- |
| 1641 |
- |
|
- |
| 1642 |
- |
case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */ |
- |
| 1643 |
- |
address = DefineRange(pstate, (CreateRangeStmt *) parsetree); |
- |
| 1644 |
- |
break; |
- |
| 1645 |
- |
|
- |
| 1646 |
- |
case T_AlterEnumStmt: /* ALTER TYPE (enum) */ |
- |
| 1647 |
- |
address = AlterEnum((AlterEnumStmt *) parsetree); |
- |
| 1648 |
- |
break; |
- |
| 1649 |
- |
|
- |
| 1650 |
- |
case T_ViewStmt: /* CREATE VIEW */ |
- |
| 1651 |
- |
EventTriggerAlterTableStart(parsetree); |
- |
| 1652 |
- |
address = DefineView((ViewStmt *) parsetree, queryString, |
- |
| 1653 |
- |
pstmt->stmt_location, pstmt->stmt_len); |
- |
| 1654 |
- |
EventTriggerCollectSimpleCommand(address, secondaryObject, |
- |
| 1655 |
- |
parsetree); |
- |
| 1656 |
- |
/* stashed internally */ |
- |
| 1657 |
- |
commandCollected = true; |
- |
| 1658 |
- |
EventTriggerAlterTableEnd(); |
- |
| 1659 |
- |
break; |
- |
| 1660 |
- |
|
- |
| 1661 |
- |
case T_CreateFunctionStmt: /* CREATE FUNCTION */ |
- |
| 1662 |
- |
address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree); |
- |
| 1663 |
- |
break; |
- |
| 1664 |
- |
|
- |
| 1665 |
- |
case T_AlterFunctionStmt: /* ALTER FUNCTION */ |
- |
| 1666 |
- |
address = AlterFunction(pstate, (AlterFunctionStmt *) parsetree); |
- |
| 1667 |
- |
break; |
- |
| 1668 |
- |
|
- |
| 1669 |
- |
case T_RuleStmt: /* CREATE RULE */ |
- |
| 1670 |
- |
address = DefineRule((RuleStmt *) parsetree, queryString); |
- |
| 1671 |
- |
break; |
- |
| 1672 |
- |
|
- |
| 1673 |
- |
case T_CreateSeqStmt: |
- |
| 1674 |
- |
address = DefineSequence(pstate, (CreateSeqStmt *) parsetree); |
- |
| 1675 |
- |
break; |
- |
| 1676 |
- |
|
- |
| 1677 |
- |
case T_AlterSeqStmt: |
- |
| 1678 |
- |
address = AlterSequence(pstate, (AlterSeqStmt *) parsetree); |
- |
| 1679 |
- |
break; |
- |
| 1680 |
- |
|
- |
| 1681 |
- |
case T_CreateTableAsStmt: |
- |
| 1682 |
- |
address = ExecCreateTableAs(pstate, (CreateTableAsStmt *) parsetree, |
- |
| 1683 |
- |
params, queryEnv, qc); |
- |
| 1684 |
- |
break; |
- |
| 1685 |
- |
|
- |
| 1686 |
- |
case T_RefreshMatViewStmt: |
- |
| 1687 |
- |
|
- |
| 1688 |
- |
/* |
- |
| 1689 |
- |
* REFRESH CONCURRENTLY executes some DDL commands internally. |
- |
| 1690 |
- |
* Inhibit DDL command collection here to avoid those commands |
- |
| 1691 |
- |
* from showing up in the deparsed command queue. The refresh |
- |
| 1692 |
- |
* command itself is queued, which is enough. |
- |
| 1693 |
- |
*/ |
- |
| 1694 |
- |
EventTriggerInhibitCommandCollection(); |
- |
| 1695 |
- |
PG_TRY(2); |
- |
| 1696 |
- |
{ |
- |
| 1697 |
- |
address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree, |
- |
| 1698 |
- |
queryString, qc); |
- |
| 1699 |
- |
} |
- |
| 1700 |
- |
PG_FINALLY(2); |
- |
| 1701 |
- |
{ |
- |
| 1702 |
- |
EventTriggerUndoInhibitCommandCollection(); |
- |
| 1703 |
- |
} |
- |
| 1704 |
- |
PG_END_TRY(2); |
- |
| 1705 |
- |
break; |
- |
| 1706 |
- |
|
- |
| 1707 |
- |
case T_CreateTrigStmt: |
- |
| 1708 |
- |
{ |
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1709 |
2649 |
CreateTrigStmt *stmt = (CreateTrigStmt *) parsetree; |
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1710 |
- |
|
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1711 |
2649 |
address = CreateTriggerFiringOn(stmt, queryString, InvalidOid, InvalidOid, |
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1712 |
- |
InvalidOid, InvalidOid, InvalidOid, |
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1713 |
- |
InvalidOid, NULL, false, |
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1714 |
- |
false, stmt->tgenabled); |
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1715 |
- |
} |
39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled |
| 1716 |
- |
break; |
- |
| 1717 |
- |
|
- |
| 1718 |
- |
case T_CreatePLangStmt: |
- |
| 1719 |
- |
address = CreateProceduralLanguage((CreatePLangStmt *) parsetree); |
- |
| 1720 |
- |
break; |
- |
| 1721 |
- |
|
- |
| 1722 |
- |
case T_CreateDomainStmt: |
- |
| 1723 |
- |
address = DefineDomain(pstate, (CreateDomainStmt *) parsetree); |
- |
| 1724 |
- |
break; |
- |
| 1725 |
- |
|
- |
| 1726 |
- |
case T_CreateConversionStmt: |
- |
| 1727 |
- |
address = CreateConversionCommand((CreateConversionStmt *) parsetree); |
- |
| 1728 |
- |
break; |
- |
| 1729 |
- |
|
- |
| 1730 |
- |
case T_CreateCastStmt: |
- |
| 1731 |
- |
address = CreateCast((CreateCastStmt *) parsetree); |
- |
| 1732 |
- |
break; |
- |
| 1733 |
- |
|
- |
| 1734 |
- |
case T_CreateOpClassStmt: |
- |
| 1735 |
- |
DefineOpClass((CreateOpClassStmt *) parsetree); |
- |
| 1736 |
- |
/* command is stashed in DefineOpClass */ |
- |
| 1737 |
- |
commandCollected = true; |
- |
| 1738 |
- |
break; |
- |
| 1739 |
- |
|
- |
| 1740 |
- |
case T_CreateOpFamilyStmt: |
- |
| 1741 |
- |
address = DefineOpFamily((CreateOpFamilyStmt *) parsetree); |
- |
| 1742 |
- |
|
- |
| 1743 |
- |
/* |
- |
| 1744 |
- |
* DefineOpFamily calls EventTriggerCollectSimpleCommand |
- |
| 1745 |
- |
* directly. |
- |
| 1746 |
- |
*/ |
- |
| 1747 |
- |
commandCollected = true; |
- |
| 1748 |
- |
break; |
- |
| 1749 |
- |
|
- |
| 1750 |
- |
case T_CreatePropGraphStmt: |
- |
| 1751 |
- |
address = CreatePropGraph(pstate, (CreatePropGraphStmt *) parsetree); |
- |
| 1752 |
- |
break; |
- |
| 1753 |
- |
|
- |
| 1754 |
- |
case T_AlterPropGraphStmt: |
- |
| 1755 |
- |
address = AlterPropGraph(pstate, (AlterPropGraphStmt *) parsetree); |
- |
| 1756 |
- |
break; |
- |
| 1757 |
- |
|
- |
| 1758 |
- |
case T_CreateTransformStmt: |
- |
| 1759 |
- |
address = CreateTransform((CreateTransformStmt *) parsetree); |
- |
| 1760 |
- |
break; |
- |
| 1761 |
- |
|
- |
| 1762 |
- |
case T_AlterOpFamilyStmt: |
- |
| 1763 |
- |
AlterOpFamily((AlterOpFamilyStmt *) parsetree); |
- |
| 1764 |
- |
/* commands are stashed in AlterOpFamily */ |
- |
| 1765 |
- |
commandCollected = true; |
- |
| 1766 |
- |
break; |
- |
| 1767 |
- |
|
- |
| 1768 |
- |
case T_AlterTSDictionaryStmt: |
- |
| 1769 |
- |
address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree); |
- |
| 1770 |
- |
break; |
- |
| 1771 |
- |
|
- |
| 1772 |
- |
case T_AlterTSConfigurationStmt: |
- |
| 1773 |
- |
AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree); |
- |
| 1774 |
- |
|
- |
| 1775 |
- |
/* |
- |
| 1776 |
- |
* Commands are stashed in MakeConfigurationMapping and |
- |
| 1777 |
- |
* DropConfigurationMapping, which are called from |
- |
| 1778 |
- |
* AlterTSConfiguration |
- |
| 1779 |
- |
*/ |
- |
| 1780 |
- |
commandCollected = true; |
- |
| 1781 |
- |
break; |
- |
| 1782 |
- |
|
- |
| 1783 |
- |
case T_AlterTableMoveAllStmt: |
- |
| 1784 |
- |
AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree); |
- |
| 1785 |
- |
/* commands are stashed in AlterTableMoveAll */ |
- |
| 1786 |
- |
commandCollected = true; |
- |
| 1787 |
- |
break; |
- |
| 1788 |
- |
|
- |
| 1789 |
- |
case T_DropStmt: |
- |
| 1790 |
- |
ExecDropStmt((DropStmt *) parsetree, isTopLevel); |
- |
| 1791 |
- |
/* no commands stashed for DROP */ |
- |
| 1792 |
- |
commandCollected = true; |
- |
| 1793 |
- |
break; |
- |
| 1794 |
- |
|
- |
| 1795 |
- |
case T_RenameStmt: |
- |
| 1796 |
- |
address = ExecRenameStmt((RenameStmt *) parsetree); |
- |
| 1797 |
- |
break; |
- |
| 1798 |
- |
|
- |
| 1799 |
- |
case T_AlterObjectDependsStmt: |
- |
| 1800 |
- |
address = |
- |
| 1801 |
- |
ExecAlterObjectDependsStmt((AlterObjectDependsStmt *) parsetree, |
- |
| 1802 |
- |
&secondaryObject); |
- |
| 1803 |
- |
break; |
- |
| 1804 |
- |
|
- |
| 1805 |
- |
case T_AlterObjectSchemaStmt: |
- |
| 1806 |
- |
address = |
- |
| 1807 |
- |
ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree, |
- |
| 1808 |
- |
&secondaryObject); |
- |
| 1809 |
- |
break; |
- |
| 1810 |
- |
|
- |
| 1811 |
- |
case T_AlterOwnerStmt: |
- |
| 1812 |
- |
address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree); |
- |
| 1813 |
- |
break; |
- |
| 1814 |
- |
|
- |
| 1815 |
- |
case T_AlterOperatorStmt: |
- |
| 1816 |
- |
address = AlterOperator((AlterOperatorStmt *) parsetree); |
- |
| 1817 |
- |
break; |
- |
| 1818 |
- |
|
- |
| 1819 |
- |
case T_AlterTypeStmt: |
- |
| 1820 |
- |
address = AlterType((AlterTypeStmt *) parsetree); |
- |
| 1821 |
- |
break; |
- |
| 1822 |
- |
|
- |
| 1823 |
- |
case T_CommentStmt: |
- |
| 1824 |
- |
address = CommentObject((CommentStmt *) parsetree); |
- |
| 1825 |
- |
break; |
- |
| 1826 |
- |
|
- |
| 1827 |
- |
case T_GrantStmt: |
- |
| 1828 |
- |
ExecuteGrantStmt((GrantStmt *) parsetree); |
- |
| 1829 |
- |
/* commands are stashed in ExecGrantStmt_oids */ |
- |
| 1830 |
- |
commandCollected = true; |
- |
| 1831 |
- |
break; |
- |
| 1832 |
- |
|
- |
| 1833 |
- |
case T_DropOwnedStmt: |
- |
| 1834 |
- |
DropOwnedObjects((DropOwnedStmt *) parsetree); |
- |
| 1835 |
- |
/* no commands stashed for DROP */ |
- |
| 1836 |
- |
commandCollected = true; |
- |
| 1837 |
- |
break; |
- |
| 1838 |
- |
|
- |
| 1839 |
- |
case T_AlterDefaultPrivilegesStmt: |
- |
| 1840 |
- |
ExecAlterDefaultPrivilegesStmt(pstate, (AlterDefaultPrivilegesStmt *) parsetree); |
- |
| 1841 |
- |
EventTriggerCollectAlterDefPrivs((AlterDefaultPrivilegesStmt *) parsetree); |
- |
| 1842 |
- |
commandCollected = true; |
- |
| 1843 |
- |
break; |
- |
| 1844 |
- |
|
- |
| 1845 |
- |
case T_CreatePolicyStmt: /* CREATE POLICY */ |
- |
| 1846 |
- |
address = CreatePolicy((CreatePolicyStmt *) parsetree); |
- |
| 1847 |
- |
break; |
- |
| 1848 |
- |
|
- |
| 1849 |
- |
case T_AlterPolicyStmt: /* ALTER POLICY */ |
- |
| 1850 |
- |
address = AlterPolicy((AlterPolicyStmt *) parsetree); |
- |
| 1851 |
- |
break; |
- |
| 1852 |
- |
|
- |
| 1853 |
- |
case T_SecLabelStmt: |
- |
| 1854 |
- |
address = ExecSecLabelStmt((SecLabelStmt *) parsetree); |
- |
| 1855 |
- |
break; |
- |
| 1856 |
- |
|
- |
| 1857 |
- |
case T_CreateAmStmt: |
- |
| 1858 |
- |
address = CreateAccessMethod((CreateAmStmt *) parsetree); |
- |
| 1859 |
- |
break; |
- |
| 1860 |
- |
|
- |
| 1861 |
- |
case T_CreatePublicationStmt: |
- |
| 1862 |
- |
address = CreatePublication(pstate, (CreatePublicationStmt *) parsetree); |
- |
| 1863 |
- |
break; |
- |
| 1864 |
- |
|
- |
| 1865 |
- |
case T_AlterPublicationStmt: |
- |
| 1866 |
- |
AlterPublication(pstate, (AlterPublicationStmt *) parsetree); |
- |
| 1867 |
- |
|
- |
| 1868 |
- |
/* |
- |
| 1869 |
- |
* AlterPublication calls EventTriggerCollectSimpleCommand |
- |
| 1870 |
- |
* directly |
- |
| 1871 |
- |
*/ |
- |
| 1872 |
- |
commandCollected = true; |
- |
| 1873 |
- |
break; |
- |
| 1874 |
- |
|
- |
| 1875 |
- |
case T_CreateSubscriptionStmt: |
- |
| 1876 |
- |
address = CreateSubscription(pstate, |
- |
| 1877 |
- |
(CreateSubscriptionStmt *) parsetree, |
- |
| 1878 |
- |
isTopLevel); |
- |
| 1879 |
- |
break; |
- |
| 1880 |
- |
|
- |
| 1881 |
- |
case T_AlterSubscriptionStmt: |
- |
| 1882 |
- |
address = AlterSubscription(pstate, |
- |
| 1883 |
- |
(AlterSubscriptionStmt *) parsetree, |
- |
| 1884 |
- |
isTopLevel); |
- |
| 1885 |
- |
break; |
- |
| 1886 |
- |
|
- |
| 1887 |
- |
case T_DropSubscriptionStmt: |
- |
| 1888 |
- |
DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel); |
- |
| 1889 |
- |
/* no commands stashed for DROP */ |
- |
| 1890 |
- |
commandCollected = true; |
- |
| 1891 |
- |
break; |
- |
| 1892 |
- |
|
- |
| 1893 |
- |
case T_CreateStatsStmt: |
- |
| 1894 |
- |
{ |
- |
| 1895 |
- |
Oid relid; |
- |
| 1896 |
- |
CreateStatsStmt *stmt = (CreateStatsStmt *) parsetree; |
- |
| 1897 |
- |
RangeVar *rel = (RangeVar *) linitial(stmt->relations); |
- |
| 1898 |
- |
|
- |
| 1899 |
- |
if (!IsA(rel, RangeVar)) |
- |
| 1900 |
- |
ereport(ERROR, |
- |
| 1901 |
- |
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
- |
| 1902 |
- |
errmsg("CREATE STATISTICS only supports relation names in the FROM clause"))); |
- |
| 1903 |
- |
|
- |
| 1904 |
- |
/* |
- |
| 1905 |
- |
* CREATE STATISTICS will influence future execution plans |
- |
| 1906 |
- |
* but does not interfere with currently executing plans. |
- |
| 1907 |
- |
* So it should be enough to take ShareUpdateExclusiveLock |
- |
| 1908 |
- |
* on relation, conflicting with ANALYZE and other DDL |
- |
| 1909 |
- |
* that sets statistical information, but not with normal |
- |
| 1910 |
- |
* queries. |
- |
| 1911 |
- |
* |
- |
| 1912 |
- |
* XXX RangeVarCallbackOwnsRelation not needed here, to |
- |
| 1913 |
- |
* keep the same behavior as before. |
- |
| 1914 |
- |
*/ |
- |
| 1915 |
- |
relid = RangeVarGetRelid(rel, ShareUpdateExclusiveLock, false); |
- |
| 1916 |
- |
|
- |
| 1917 |
- |
/* Run parse analysis ... */ |
- |
| 1918 |
- |
stmt = transformStatsStmt(relid, stmt, queryString); |
- |
| 1919 |
- |
|
- |
| 1920 |
- |
address = CreateStatistics(stmt, true); |
- |
| 1921 |
- |
} |
- |
| 1922 |
- |
break; |
- |
| 1923 |
- |
|
- |
| 1924 |
- |
case T_AlterStatsStmt: |
- |
| 1925 |
- |
address = AlterStatistics((AlterStatsStmt *) parsetree); |
- |
| 1926 |
- |
break; |
- |
| 1927 |
- |
|
- |
| 1928 |
- |
case T_AlterCollationStmt: |
- |
| 1929 |
- |
address = AlterCollation((AlterCollationStmt *) parsetree); |
- |
| 1930 |
- |
break; |
- |
| 1931 |
- |
|
- |
| 1932 |
- |
default: |
- |
| 1933 |
- |
elog(ERROR, "unrecognized node type: %d", |
- |
| 1934 |
- |
(int) nodeTag(parsetree)); |
- |
| 1935 |
- |
break; |
- |
| 1936 |
- |
} |
- |
| 1937 |
- |
|
- |
| 1938 |
- |
/* |
- |
| 1939 |
- |
* Remember the object so that ddl_command_end event triggers have |
- |
| 1940 |
- |
* access to it. |
- |
| 1941 |
- |
*/ |
- |
| 1942 |
- |
if (!commandCollected) |
- |
| 1943 |
- |
EventTriggerCollectSimpleCommand(address, secondaryObject, |
- |
| 1944 |
- |
parsetree); |
- |
| 1945 |
- |
|
- |
| 1946 |
- |
if (isCompleteQuery) |
- |
| 1947 |
- |
{ |
- |
| 1948 |
- |
EventTriggerSQLDrop(parsetree); |
- |
| 1949 |
- |
EventTriggerDDLCommandEnd(parsetree); |
- |
| 1950 |
- |
} |
- |
| 1951 |
- |
} |
- |
| 1952 |
- |
PG_FINALLY(); |
- |
| 1953 |
- |
{ |
- |
| 1954 |
- |
if (needCleanup) |
- |
| 1955 |
- |
EventTriggerEndCompleteQuery(); |
- |
| 1956 |
- |
} |
- |
| 1957 |
- |
PG_END_TRY(); |
- |
| 1958 |
- |
} |
- |