Thread: Coding help
Hi guys, I've asked this of a few people now, but I haven't managed to get a straightforward solution. I'm working on COMMENT ON LARGE OBJECT. If you could help me with this one, it would be really cool. Other than this, comment on language, conversion, cast and operator class are all done. This is my grammar snippet. NumericOnly seems to be the one to use - that's what CREATE SEQUENCE uses for its large number support, and I have to support large OIDs I presume. I could also use IntegerOnly perhaps, I don't know: | COMMENT ON LARGE OBJECT NumericOnly IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype= OBJECT_LARGEOBJECT; n->objname = makeList1(makeAConst($5)); n->objargs = NIL; n->comment= $7; $$ = (Node *) n; } This is my comment function: static void CommentLargeObject(List *qualname, char *comment) { /* This is what I cannot figure out - how do I change the Node which is the first element in the qualname to an actual Oid type??? */ Oid loid = somehow_get_oid_from(lfirst(qualname)); Oid classoid; /* check that the large object exists */ if (!LargeObjectExists(loid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", loid))); classoid = get_system_catalog_relid(LargeObjectRelationName); CreateComments(loid, classoid, 0, comment); } The problem is extracting the oid from the qualname list. I just can't figure it out. I've searched the codebase but there doesn't seem to be anywhere else that actually does this, like this. I've tried all sorts of things, but I can't figure it out... Thanks for any help, Chris
I guess you are asking how to get the NumericOnly converted to an oid, and I see from the code that there are very few places where we allow oid's to be supplied directly. Most oid's come in as part of our numberic conversion code. The only idea I have is to call oidin() to do the conversion from string to oid. I see this in copy.c: loaded_oid = DatumGetObjectId(DirectFunctionCall1(oidin, CStringGetDatum(string))); if (loaded_oid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), errmsg("invalid OID in COPY data"))); I would give that a try. --------------------------------------------------------------------------- Christopher Kings-Lynne wrote: > Hi guys, > > I've asked this of a few people now, but I haven't managed to get a > straightforward solution. > > I'm working on COMMENT ON LARGE OBJECT. > > If you could help me with this one, it would be really cool. Other than > this, comment on language, conversion, cast and operator class are all done. > > This is my grammar snippet. NumericOnly seems to be the one to use - > that's what CREATE SEQUENCE uses for its large number support, and I > have to support large OIDs I presume. I could also use IntegerOnly > perhaps, I don't know: > > | COMMENT ON LARGE OBJECT NumericOnly IS comment_text > { > CommentStmt *n = makeNode(CommentStmt); > n->objtype = OBJECT_LARGEOBJECT; > n->objname = makeList1(makeAConst($5)); > n->objargs = NIL; > n->comment = $7; > $$ = (Node *) n; > } > > This is my comment function: > > static void > CommentLargeObject(List *qualname, char *comment) > { > /* This is what I cannot figure out - how do I change the Node > which is the first element in the qualname to an actual Oid type??? */ > Oid loid = somehow_get_oid_from(lfirst(qualname)); > Oid classoid; > > /* check that the large object exists */ > if (!LargeObjectExists(loid)) > ereport(ERROR, > (errcode(ERRCODE_UNDEFINED_OBJECT), > errmsg("large object %u does not exist", loid))); > > classoid = get_system_catalog_relid(LargeObjectRelationName); > > CreateComments(loid, classoid, 0, comment); > } > > The problem is extracting the oid from the qualname list. I just can't > figure it out. I've searched the codebase but there doesn't seem to be > anywhere else that actually does this, like this. > > I've tried all sorts of things, but I can't figure it out... > > Thanks for any help, > > Chris > > > > ---------------------------(end of broadcast)--------------------------- > TIP 4: Don't 'kill -9' the postmaster > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
> The only idea I have is to call oidin() to do the conversion from string > to oid. I see this in copy.c: > > loaded_oid = DatumGetObjectId(DirectFunctionCall1(oidin, > CStringGetDatum(string))); > if (loaded_oid == InvalidOid) > ereport(ERROR, > (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), > errmsg("invalid OID in COPY data"))); > > I would give that a try. Yes but in this case, the Node is parsed like this: | COMMENT ON LARGE OBJECT NumericOnly IS comment_text { ... n->objname = makeList1(makeAConst($5)); ... $$ = (Node *) n; } So there is no CString to convert to a Datum... Chris
Christopher Kings-Lynne wrote: > > > The only idea I have is to call oidin() to do the conversion from string > > to oid. I see this in copy.c: > > > > loaded_oid = DatumGetObjectId(DirectFunctionCall1(oidin, > > CStringGetDatum(string))); > > if (loaded_oid == InvalidOid) > > ereport(ERROR, > > (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), > > errmsg("invalid OID in COPY data"))); > > > > I would give that a try. > > Yes but in this case, the Node is parsed like this: > > | COMMENT ON LARGE OBJECT NumericOnly IS comment_text > { > > ... > > > n->objname = makeList1(makeAConst($5)); > > ... > > $$ = (Node *) n; > } > > So there is no CString to convert to a Datum... But I see makeAConst as:static Node *makeAConst(Value *v){ Node *n; switch (v->type) { case T_Float: n = makeFloatConst(v->val.str); break; case T_Integer: n = makeIntConst(v->val.ival); break; case T_String: default: n = makeStringConst(v->val.str,NULL); break; } return n;} which uses makeStringConst(). -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes: > | COMMENT ON LARGE OBJECT NumericOnly IS comment_text > n->objname = makeList1(makeAConst($5)); Forget the makeAConst step --- it's just wasted cycles. In the execution routine, you can use code comparable to define.c's defGetInt64() to convert the Value node into a numeric OID, ie, either do intVal() or a call of oidin(). regards, tom lane
>>| COMMENT ON LARGE OBJECT NumericOnly IS comment_text >> n->objname = makeList1(makeAConst($5)); > > > Forget the makeAConst step --- it's just wasted cycles. In the > execution routine, you can use code comparable to define.c's defGetInt64() > to convert the Value node into a numeric OID, ie, either do intVal() or > a call of oidin(). I thought the whole problem here is that OIDs are unsigned ints, hence intVal() won't allow the highest OIDs? If that's not the case, then the easy solution is to just use an IConst or whateverit's called. (Which I had working before). Chris
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes: >> ... you can use code comparable to define.c's defGetInt64() >> to convert the Value node into a numeric OID, ie, either do intVal() or >> a call of oidin(). > I thought the whole problem here is that OIDs are unsigned ints, hence > intVal() won't allow the highest OIDs? Exactly. That's why you need to handle T_Float too. See the int8 example, which has just the same problem. regards, tom lane
>>I thought the whole problem here is that OIDs are unsigned ints, hence >>intVal() won't allow the highest OIDs? > > > Exactly. That's why you need to handle T_Float too. See the int8 > example, which has just the same problem. It occurs to me then that I could just then use FloatOnly in the grammar and then just attempt to coerce that to an Oid using oidin? Floats are stored as strings, so that'd be OK, and the oidin function would barf if it was an illegal uint? Chris
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes: > It occurs to me then that I could just then use FloatOnly in the grammar I don't think so, unless you are proposing something very odd in the lexer to force it to treat an integer literal as a float in this one context. What is the problem with following the lead of the existing code? regards, tom lane