Thread

  1. Re: [HACKERS] How do I construct a varlena?

    Oliver Elphick <olly@lfix.co.uk> — 1998-08-09T19:45:24Z

    Maarten Boekhold wrote:
      >On Tue, 4 Aug 1998, Oliver Elphick wrote:
      >
      >> Can you tell me, please, how to construct a varlena (to be returned by
      >> a function).
      >> 
      >> I see it is declared as an int and a 1-byte array; I don't know how to
      >> assign a longer string in place of that 1-byte array; the compiler
      >> complains about incompatible types, whatever I do.
      >
      >If I'm correct:
      >
      >	malloc(sizeof(VARLENA) + l);
      >
      >where 'l' is the length of the string you want to put in (without the
      >trailing '\0').
     
    Thanks for your reply; I've been away a few days so I've only just seen it.
    
    My problem is in how to get the compiler to treat the malloced space as
    a varlena.
    
    I have this (abridged) C code, to be used with 
    CREATE FUNCTION cname(bpchar, bpchar, bpchar) returns bpchar ...:
    
    
      char *cxname;
    
      text cname (text s, text t, text f)
      {
            text *result;
      ...
            cxname = realloc((void *) cxname, strlen(tmp)+sizeof(struct varlena));
            strcpy(cxname+sizeof(int32), tmp);
    ->      result = &((struct varlena) cxname);
            result->vl_len = strlen(tmp);
    
            return *result;
      }
    
    but the compiler gives the error `conversion to non-scalar type requested'
    at the marked line.
    
    Once I know how to do this, I will add it to the examples in the CREATE
    FUNCTION documentation, since it will no doubt be helpful to others.
    
    -- 
    Oliver Elphick                                Oliver.Elphick@lfix.co.uk
    Isle of Wight                              http://www.lfix.co.uk/oliver
                   PGP key from public servers; key ID 32B8FAA1
                     ========================================
         "...ask, and ye shall receive, that your joy may be 
          full."      John 16:24 
    
    
    
    
  2. Re: [HACKERS] How do I construct a varlena?

    Thomas Lockhart <lockhart@alumni.caltech.edu> — 1998-08-10T02:21:57Z

    > My problem is in how to get the compiler to treat the malloced space 
    > as a varlena.
    > I have this (abridged) C code, to be used with
    > CREATE FUNCTION cname(bpchar, bpchar, bpchar) returns bpchar ...:
    > 
    >   char *cxname;
    > 
    >   text cname (text s, text t, text f)
        text *cname (text s, text t, text f)
    >   {
    >         text *result;
    >   ...
    >         cxname = realloc((void *) cxname,
    >                  strlen(tmp)+sizeof(struct varlena));
    strcpy is dangerous because it will copy the trailing null, while text
    and other varlena types are not guaranteed to be null-terminated. Better
    to use memmove() or strncpy().
    >         strcpy(cxname+sizeof(int32), tmp);
              strcpy(cxname+sizeof(result->vl_len), tmp);
    or
              strcpy(cxname+sizeof(VARHDRSZ), tmp);
    not sure where tmp came from...
    > ->      result = &((struct varlena) cxname);
    cxname is already a pointer. And why not make it a pointer to text
    instead of a pointer to char?
              result = ((text *) cxname);
    >         result->vl_len = strlen(tmp);
    > 
    >         return *result;
    >   }
    > Once I know how to do this, I will add it to the examples in the 
    > CREATE FUNCTION documentation, since it will no doubt be helpful to 
    > others.
    
    There is already documentation on this (though it could stand to be
    cleaned up and augmented) in doc/src/sgml/xfunc.sgml. This appears in
    the Programmer's Guide in the chapter titled "Extending SQL: Functions".
    
    If you want, it's probably OK to keep the SQL reference docs pretty
    simple, and if there is an example of C source code it could be shown
    but then described more completely in the Programmer's Guide. Or we
    could just mention that there _are_ examples in the Programmer's Guide
    and leave it at that.
    
    There is some code following which gives a (simpler) example...
    
                       - Tom
    
    >From the varlena.c file in backend/utils/adt/:
    
    /*
     *      textin          - converts "..." to internal representation
     */
    text *
    textin(char *inputText)
    {
        text       *result;
        int         len;
    
        if (inputText == NULL)
            return (NULL);
    
        len = strlen(inputText) + VARHDRSZ;
        result = (text *) palloc(len);
        VARSIZE(result) = len;
    
        memmove(VARDATA(result), inputText, len - VARHDRSZ);
    
    #ifdef CYR_RECODE
        convertstr(VARDATA(result), len - VARHDRSZ, 0);
    #endif
    
        return (result);
    }
    
    
  3. Re: [HACKERS] How do I construct a varlena?

    Maarten Boekhold <maartenb@dutepp2.et.tudelft.nl> — 1998-08-10T07:20:17Z

    > My problem is in how to get the compiler to treat the malloced space as
    > a varlena.
    > 
    > I have this (abridged) C code, to be used with 
    > CREATE FUNCTION cname(bpchar, bpchar, bpchar) returns bpchar ...:
    > 
    > 
    >   char *cxname;
    > 
    >   text cname (text s, text t, text f)
    >   {
    >         text *result;
    >   ...
    >         cxname = realloc((void *) cxname, strlen(tmp)+sizeof(struct varlena));
    >         strcpy(cxname+sizeof(int32), tmp);
    > ->      result = &((struct varlena) cxname);
    >         result->vl_len = strlen(tmp);
    > 
    >         return *result;
    >   }
    > 
    > but the compiler gives the error `conversion to non-scalar type requested'
    > at the marked line.
    
    I gues something like this should work:
    
        struct varlena *cxname
    
        cxname = (struct varlena *)
    		realloc(cxname, strlen(tmp) + VARHDRSZ);
        strcpy(cxname->vl_dat, tmp); /* maybe '&cxname->vl_dat' */
        return cxname;
    
    I don't think it's possible to 'return *cxname', cos the compiler will
    only return the part of your data.
    
    Most of this is from head, so check on things if they don't work immediately.
    
    Maarten
    
    _____________________________________________________________________________
    | TU Delft, The Netherlands, Faculty of Information Technology and Systems  |
    |                   Department of Electrical Engineering                    |
    |           Computer Architecture and Digital Technique section             |
    |                          M.Boekhold@et.tudelft.nl                         |
    -----------------------------------------------------------------------------