/* * transformTargetList() * Turns a list of ResTarget's into a list of TargetEntry's. * * This code acts mostly the same for SELECT, UPDATE, or RETURNING lists; * the main thing is to transform the given expressions (the "val" fields). * The exprKind parameter distinguishes these cases when necesssary. */ List * transformTargetList(ParseState *pstate, List *targetlist, ParseExprKind exprKind) { List *p_target = NIL; ListCell *o_target; /* Shouldn't have any leftover multiassign items at start */ Assert(pstate->p_multiassign_exprs == NIL); foreach(o_target, targetlist) { ResTarget *res = (ResTarget *) lfirst(o_target); /* * Check for "something.*". Depending on the complexity of the * "something", the star could appear as the last field in ColumnRef, * or as the last indirection item in A_Indirection. */ if (IsA(res->val, ColumnRef)) { ColumnRef *cref = (ColumnRef *) res->val; if (IsA(llast(cref->fields), A_Star)) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandColumnRefStar(pstate, cref, true)); continue; } } else if (IsA(res->val, A_Indirection)) { A_Indirection *ind = (A_Indirection *) res->val; if (IsA(llast(ind->indirection), A_Star)) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandIndirectionStar(pstate, ind, true, exprKind)); continue; } } /* * Not "something.*", so transform as a single expression */ p_target = lappend(p_target, transformTargetEntry(pstate, res->val, NULL, exprKind, res->name, false)); }
/* * transformTargetList() * Turns a list of ResTarget's into a list of TargetEntry's. * * At this point, we don't care whether we are doing SELECT, INSERT, * or UPDATE; we just transform the given expressions (the "val" fields). */ List * transformTargetList(ParseState *pstate, List *targetlist) { List *p_target = NIL; ListCell *o_target; foreach(o_target, targetlist) { ResTarget *res = (ResTarget *) lfirst(o_target); /* * Check for "something.*". Depending on the complexity of the * "something", the star could appear as the last name in ColumnRef, * or as the last indirection item in A_Indirection. */ if (IsA(res->val, ColumnRef)) { ColumnRef *cref = (ColumnRef *) res->val; if (strcmp(strVal(llast(cref->fields)), "*") == 0) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandColumnRefStar(pstate, cref, true)); continue; } } else if (IsA(res->val, A_Indirection)) { A_Indirection *ind = (A_Indirection *) res->val; Node *lastitem = llast(ind->indirection); if (IsA(lastitem, String) && strcmp(strVal(lastitem), "*") == 0) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandIndirectionStar(pstate, ind, true)); continue; } } /* * Not "something.*", so transform as a single expression */ p_target = lappend(p_target, transformTargetEntry(pstate, res->val, NULL, res->name, false)); }
/* * sepgsql_xact_callback * * A callback routine of transaction commit/abort/prepare. Commit or abort * changes in the client_label_pending list. */ static void sepgsql_xact_callback(XactEvent event, void *arg) { if (event == XACT_EVENT_COMMIT) { if (client_label_pending != NIL) { pending_label *plabel = llast(client_label_pending); char *new_label; if (plabel->label) new_label = MemoryContextStrdup(TopMemoryContext, plabel->label); else new_label = NULL; if (client_label_committed) pfree(client_label_committed); client_label_committed = new_label; /* * XXX - Note that items of client_label_pending are allocated on * CurTransactionContext, thus, all acquired memory region shall * be released implicitly. */ client_label_pending = NIL; } } else if (event == XACT_EVENT_ABORT) client_label_pending = NIL; }
/* * xfrm_tgt_list() * Turns a list of ResTarget's into a list of TargetEntry's. * * At this point, we don't care whether we are doing SELECT, INSERT, * or UPDATE; we just transform the given expressions (the "val" fields). */ struct list* xfrm_tgt_list(parse_state_s* pstate, struct list* targetlist) { struct list *p_target = NIL; struct list_cell *o_target; foreach(o_target, targetlist) { ResTarget *res = (ResTarget *) lfirst(o_target); /* * Check for "something.*". Depending on the complexity of the * "something", the star could appear as the last field in ColumnRef, * or as the last indirection item in A_Indirection. */ if (IS_A(res->val, ColumnRef)) { column_ref_n *cref; cref = (column_ref_n *) res->val; if (IS_A(llast(cref->fields), A_Star)) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandColumnRefStar(pstate, cref, true)); continue; } } else if (IS_A(res->val, A_Indirection)) { A_Indirection *ind; ind = (A_Indirection*) res->val; if (IS_A(llast(ind->indirection), A_Star)) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandIndirectionStar(pstate, ind, true)); continue; } } /* * Not "something.*", so transform as a single expression */ p_target = lappend(p_target, xfrm_tgt_entry(pstate, res->val, NULL, res->name, false)); }
void joinQueryRTEs(Query *query) { ListCell *lc; JoinExpr *newJoin; List *fromItems; List *subJoins; /* if query has only one or no range table entry return */ if (list_length(query->jointree->fromlist) <= 1) return; subJoins = NIL; fromItems = query->jointree->fromlist; query->jointree->fromlist = NIL; /* create a join tree that joins all from items */ lc = fromItems->head; newJoin = createJoinExpr (query, JOIN_INNER); newJoin->quals = (Node *) makeBoolConst(true, false); newJoin->larg = (Node *) lfirst(lc); lc = lc ->next; newJoin->rarg = (Node *) lfirst(lc); subJoins = lappend(subJoins, newJoin); for(lc = lc->next; lc != NULL; lc = lc->next) { newJoin = createJoinExpr (query, JOIN_INNER); /* set join condition to true */ newJoin->quals = (Node *) makeBoolConst(true, false); /* set children */ newJoin->rarg = (Node *) llast(subJoins); newJoin->larg = (Node *) lfirst(lc); /* append to join list */ subJoins = lappend(subJoins, newJoin); } /* create from list as new top join */ query->jointree->fromlist = list_make1(newJoin); adaptRTEsForJoins(subJoins, query, "query_rte_joined"); }
/* * sepgsql_get_client_label * * Returns the current security label of the client. All code should use this * routine to get the current label, instead of referring to the client_label_* * variables above. */ char * sepgsql_get_client_label(void) { /* trusted procedure client label override */ if (client_label_func) return client_label_func; /* uncommitted sepgsql_setcon() value */ if (client_label_pending) { pending_label *plabel = llast(client_label_pending); if (plabel->label) return plabel->label; } else if (client_label_committed) return client_label_committed; /* set by sepgsql_setcon() committed */ /* default label */ Assert(client_label_peer != NULL); return client_label_peer; }
virtual std::string operator()(PtbPsTree::const_depth_first_iterator& cdfi, const PtbPsTree& tree) const { typedef PtbPsTree::const_depth_first_iterator const_iterator; typedef PtbPsTree::const_leaf_iterator const_leaf_iterator; std::stringstream ss(std::stringstream::in |std::stringstream::out); const_iterator copy = cdfi; const_iterator copycopy = copy; ss << *cdfi << "^"; //don't process terminals and preterminals if(copy->leaf()) { return ""; } else { copycopy.down_first(); if(copycopy->leaf()) { return ""; } } unsigned n = tree.subtree(cdfi).number_of_leaves(); // bin 1,2,3,4,5, [6,10[, >=10 if(n >= 10) n = 10; else if(n>5) n = 6; ss << n << "^"; //go to the first daughter do { copy.down_first(); } while(!copy->leaf()); //go to the last daughter copycopy = cdfi; do { copycopy.down_last(); } while(!copycopy->leaf()); const_leaf_iterator lfirst(&tree, copy.get_node()); const_leaf_iterator llast(&tree, copycopy.get_node()); for (unsigned i = 0; i < nfirst; ++i) { const_iterator d = lfirst; d.up(); ss << *d << "^"; ++lfirst; if(lfirst == tree.lend()) break; } ss << "<>"; for (unsigned i = 0; i < nlast; ++i) { const_iterator d = llast; d.up(); ss << *d << "^"; --llast; if(llast == tree.lend()) break; } return ss.str(); }
/* ---------------------------------------------------------------- * * ---------------------------------------------------------------- */ Datum int4notin(PG_FUNCTION_ARGS) { int32 not_in_arg = PG_GETARG_INT32(0); text *relation_and_attr = PG_GETARG_TEXT_P(1); List *names; int nnames; RangeVar *relrv; char *attribute; Relation relation_to_scan; int32 integer_value; HeapTuple current_tuple; HeapScanDesc scan_descriptor; bool isNull, retval; int attrid; Datum value; /* Parse the argument */ names = textToQualifiedNameList(relation_and_attr); nnames = list_length(names); if (nnames < 2) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("invalid name syntax"), errhint("Must provide \"relationname.columnname\"."))); attribute = strVal(llast(names)); names = list_truncate(names, nnames - 1); relrv = makeRangeVarFromNameList(names); /* Open the relation and get a relation descriptor */ relation_to_scan = heap_openrv(relrv, AccessShareLock); /* Find the column to search */ attrid = attnameAttNum(relation_to_scan, attribute, true); scan_descriptor = heap_beginscan(relation_to_scan, SnapshotNow, 0, (ScanKey) NULL); retval = true; /* do a scan of the relation, and do the check */ while ((current_tuple = heap_getnext(scan_descriptor, ForwardScanDirection)) != NULL) { value = heap_getattr(current_tuple, (AttrNumber) attrid, RelationGetDescr(relation_to_scan), &isNull); if (isNull) continue; integer_value = DatumGetInt32(value); if (not_in_arg == integer_value) { retval = false; break; /* can stop scanning now */ } } /* close the relation */ heap_endscan(scan_descriptor); heap_close(relation_to_scan, AccessShareLock); PG_RETURN_BOOL(retval); }
/* * transformTargetList() * Turns a list of ResTarget's into a list of TargetEntry's. * * At this point, we don't care whether we are doing SELECT, INSERT, * or UPDATE; we just transform the given expressions (the "val" fields). */ List * transformTargetList(ParseState *pstate, List *targetlist) { List *p_target = NIL; ListCell *o_target; ParseStateBreadCrumb savebreadcrumb; /* CDB: Push error location stack. Must pop before return! */ Assert(pstate); savebreadcrumb = pstate->p_breadcrumb; pstate->p_breadcrumb.pop = &savebreadcrumb; foreach(o_target, targetlist) { ResTarget *res = (ResTarget *) lfirst(o_target); /* CDB: Drop a breadcrumb in case of error. */ pstate->p_breadcrumb.node = (Node *)res; /* * Check for "something.*". Depending on the complexity of the * "something", the star could appear as the last name in ColumnRef, * or as the last indirection item in A_Indirection. */ if (IsA(res->val, ColumnRef)) { ColumnRef *cref = (ColumnRef *) res->val; if (strcmp(strVal(llast(cref->fields)), "*") == 0) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandColumnRefStar(pstate, cref, true)); continue; } } else if (IsA(res->val, A_Indirection)) { A_Indirection *ind = (A_Indirection *) res->val; Node *lastitem = llast(ind->indirection); if (IsA(lastitem, String) && strcmp(strVal(lastitem), "*") == 0) { /* It is something.*, expand into multiple items */ p_target = list_concat(p_target, ExpandIndirectionStar(pstate, ind, true)); continue; } } /* * Not "something.*", so transform as a single expression */ p_target = lappend(p_target, transformTargetEntry(pstate, res->val, NULL, res->name, false)); }
/* * CStoreBeginWrite initializes a cstore data load operation and returns a table * handle. This handle should be used for adding the row values and finishing the * data load operation. If the cstore footer file already exists, we read the * footer and then seek to right after the last stripe where the new stripes * will be added. */ TableWriteState * CStoreBeginWrite(const char *filename, CompressionType compressionType, uint64 stripeMaxRowCount, uint32 blockRowCount, TupleDesc tupleDescriptor) { TableWriteState *writeState = NULL; FILE *tableFile = NULL; StringInfo tableFooterFilename = NULL; TableFooter *tableFooter = NULL; FmgrInfo **comparisonFunctionArray = NULL; MemoryContext stripeWriteContext = NULL; uint64 currentFileOffset = 0; uint32 columnCount = 0; uint32 columnIndex = 0; struct stat statBuffer; int statResult = 0; bool *columnMaskArray = NULL; ColumnBlockData **blockData = NULL; tableFooterFilename = makeStringInfo(); appendStringInfo(tableFooterFilename, "%s%s", filename, CSTORE_FOOTER_FILE_SUFFIX); statResult = stat(tableFooterFilename->data, &statBuffer); if (statResult < 0) { tableFile = AllocateFile(filename, "w"); if (tableFile == NULL) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for writing: %m", filename))); } tableFooter = palloc0(sizeof(TableFooter)); tableFooter->blockRowCount = blockRowCount; tableFooter->stripeMetadataList = NIL; } else { tableFile = AllocateFile(filename, "r+"); if (tableFile == NULL) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for writing: %m", filename))); } tableFooter = CStoreReadFooter(tableFooterFilename); } /* * If stripeMetadataList is not empty, jump to the position right after * the last position. */ if (tableFooter->stripeMetadataList != NIL) { StripeMetadata *lastStripe = NULL; uint64 lastStripeSize = 0; int fseekResult = 0; lastStripe = llast(tableFooter->stripeMetadataList); lastStripeSize += lastStripe->skipListLength; lastStripeSize += lastStripe->dataLength; lastStripeSize += lastStripe->footerLength; currentFileOffset = lastStripe->fileOffset + lastStripeSize; errno = 0; fseekResult = fseeko(tableFile, currentFileOffset, SEEK_SET); if (fseekResult != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not seek in file \"%s\": %m", filename))); } } /* get comparison function pointers for each of the columns */ columnCount = tupleDescriptor->natts; comparisonFunctionArray = palloc0(columnCount * sizeof(FmgrInfo *)); for (columnIndex = 0; columnIndex < columnCount; columnIndex++) { FmgrInfo *comparisonFunction = NULL; FormData_pg_attribute *attributeForm = tupleDescriptor->attrs[columnIndex]; if (!attributeForm->attisdropped) { Oid typeId = attributeForm->atttypid; comparisonFunction = GetFunctionInfoOrNull(typeId, BTREE_AM_OID, BTORDER_PROC); } comparisonFunctionArray[columnIndex] = comparisonFunction; } /* * We allocate all stripe specific data in the stripeWriteContext, and * reset this memory context once we have flushed the stripe to the file. * This is to avoid memory leaks. */ stripeWriteContext = AllocSetContextCreate(CurrentMemoryContext, "Stripe Write Memory Context", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); columnMaskArray = palloc(columnCount * sizeof(bool)); memset(columnMaskArray, true, columnCount); blockData = CreateEmptyBlockDataArray(columnCount, columnMaskArray, blockRowCount); writeState = palloc0(sizeof(TableWriteState)); writeState->tableFile = tableFile; writeState->tableFooterFilename = tableFooterFilename; writeState->tableFooter = tableFooter; writeState->compressionType = compressionType; writeState->stripeMaxRowCount = stripeMaxRowCount; writeState->tupleDescriptor = tupleDescriptor; writeState->currentFileOffset = currentFileOffset; writeState->comparisonFunctionArray = comparisonFunctionArray; writeState->stripeBuffers = NULL; writeState->stripeSkipList = NULL; writeState->stripeWriteContext = stripeWriteContext; writeState->blockDataArray = blockData; writeState->compressionBuffer = NULL; return writeState; }