/[pgestraier]/trunk/pgest.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/pgest.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 44 by dpavlin, Sat Sep 10 22:51:03 2005 UTC revision 85 by dpavlin, Sat Feb 3 17:13:07 2007 UTC
# Line 25  Line 25 
25  #include "funcapi.h"  #include "funcapi.h"
26  #include "utils/builtins.h"  #include "utils/builtins.h"
27  #include "utils/array.h"  #include "utils/array.h"
28    #include "utils/lsyscache.h"
29  #include "miscadmin.h"  #include "miscadmin.h"
30    #include "commands/trigger.h"
31    #include "executor/spi.h"
32    
33  #include <estraier.h>  #include <estraier.h>
34  #include <cabin.h>  #include <cabin.h>
35  #include <estnode.h>  #include <estnode.h>
# Line 40  Line 44 
44   #define SortMem 16 * 1024   #define SortMem 16 * 1024
45  #endif  #endif
46    
47    #ifdef PG_MODULE_MAGIC
48    PG_MODULE_MAGIC;
49    #endif
50    
51  #define ATTR_DELIMITER "{{!}}"  #define ATTR_DELIMITER "{{!}}"
52    #define HINTS_PREFIX "HINTS."
53    
54  /* prototype */  /* prototype */
55  char *attr2text(ESTDOC *doc, char *attr);  char *attr2text(ESTDOC *doc, char *attr);
56  char *node_attr2text(ESTRESDOC *rdoc, char *attr);  char *node_attr2text(ESTRESDOC *rdoc, char *attr);
57    void cond_add_attr(ESTCOND *cond, char *attr);
58    
59    
60  /* work in progress */  /* work in progress */
# Line 77  Datum pgest_attr(PG_FUNCTION_ARGS) Line 87  Datum pgest_attr(PG_FUNCTION_ARGS)
87          ESTDB *db;          ESTDB *db;
88          ESTCOND *cond;          ESTCOND *cond;
89          ESTDOC *doc;          ESTDOC *doc;
         const CBLIST *texts;  
90          int ecode, *est_result, resnum;          int ecode, *est_result, resnum;
91          int limit = 0;          int limit = 0;
92          int offset = 0;          int offset = 0;
# Line 208  Datum pgest_attr(PG_FUNCTION_ARGS) Line 217  Datum pgest_attr(PG_FUNCTION_ARGS)
217          /* minimum valid attribute length is 10: @a STREQ a */          /* minimum valid attribute length is 10: @a STREQ a */
218          if (! PG_ARGISNULL(2) && strlen(attr) >= 10) {          if (! PG_ARGISNULL(2) && strlen(attr) >= 10) {
219                  elog(DEBUG1,"attributes: %s", attr);                  elog(DEBUG1,"attributes: %s", attr);
220                  char *curr_attr;                  cond_add_attr(cond, attr);
                 curr_attr = strtok(attr, ATTR_DELIMITER);  
                 while (curr_attr) {  
                         elog(DEBUG1,"est_cond_add_attr(%s)", curr_attr);  
                         est_cond_add_attr(cond, curr_attr);  
                         curr_attr = strtok(NULL, ATTR_DELIMITER);  
                 }  
221          }          }
222    
223          /* set the search phrase to the search condition object */          /* set the search phrase to the search condition object */
# Line 246  Datum pgest_attr(PG_FUNCTION_ARGS) Line 249  Datum pgest_attr(PG_FUNCTION_ARGS)
249    
250          elog(DEBUG1, "pgest_attr: found %d hits for %s", resnum, query);          elog(DEBUG1, "pgest_attr: found %d hits for %s", resnum, query);
251    
   
252          values = (char **) palloc(ncols * sizeof(char *));          values = (char **) palloc(ncols * sizeof(char *));
253    
254          for (i = 0; i < nrows; i++)          for (i = 0; i < nrows; i++)
# Line 254  Datum pgest_attr(PG_FUNCTION_ARGS) Line 256  Datum pgest_attr(PG_FUNCTION_ARGS)
256    
257                  /* get result from estraier */                  /* get result from estraier */
258                  if (! ( doc = est_db_get_doc(db, est_result[i + offset], 0)) ) {                  if (! ( doc = est_db_get_doc(db, est_result[i + offset], 0)) ) {
259                          elog(INFO, "can't find result %d", i + offset);                          elog(INFO, "pgest_attr: can't find result %d", i + offset);
260                  } else {                  } else {
261                          elog(DEBUG1, "URI: %s\n Title: %s\n",                          elog(DEBUG1, "URI: %s\n Title: %s\n",
262                                  est_doc_attr(doc, "@uri"),                                  est_doc_attr(doc, "@uri"),
# Line 286  Datum pgest_attr(PG_FUNCTION_ARGS) Line 288  Datum pgest_attr(PG_FUNCTION_ARGS)
288                  /* now store it */                  /* now store it */
289                  tuplestore_puttuple(tupstore, tuple);                  tuplestore_puttuple(tupstore, tuple);
290    
   
291                  /* delete estraier document object */                  /* delete estraier document object */
292                  est_doc_delete(doc);                  if (doc) est_doc_delete(doc);
293          }          }
294    
295          tuplestore_donestoring(tupstore);          tuplestore_donestoring(tupstore);
# Line 323  char *attr2text(ESTDOC *doc, char *attr) Line 324  char *attr2text(ESTDOC *doc, char *attr)
324          int len;          int len;
325          int attrlen;          int attrlen;
326    
327          elog(DEBUG1, "doc: %08x, attr: %s", doc, attr);          if (! doc) return (Datum) NULL;
328    
329            elog(DEBUG1, "doc: %p, attr: %s", doc, attr);
330    
331          if ( (attrval = est_doc_attr(doc, attr)) && (attrlen = strlen(attrval)) ) {          if ( (attrval = est_doc_attr(doc, attr)) && (attrlen = strlen(attrval)) ) {
332                  val = (char *) palloc(attrlen * sizeof(char));                  val = (char *) palloc(attrlen * sizeof(char));
# Line 355  char *attr2text(ESTDOC *doc, char *attr) Line 358  char *attr2text(ESTDOC *doc, char *attr)
358   *   *
359   */   */
360    
361    /* select * from pgest( */
362    #define _arg_node_uri 0
363    #define _arg_login 1
364    #define _arg_passwd 2
365    #define _arg_depth 3
366    #define _arg_query 4
367    #define _arg_attr 5
368    #define _arg_order 6
369    #define _arg_limit 7
370    #define _arg_offset 8
371    #define _arg_attr_array 9
372    /* as (foo text, ... ); */
373    
374    
375  PG_FUNCTION_INFO_V1(pgest_node);  PG_FUNCTION_INFO_V1(pgest_node);
376  Datum pgest_node(PG_FUNCTION_ARGS)  Datum pgest_node(PG_FUNCTION_ARGS)
377  {  {
378          ArrayType       *attr_arr = PG_GETARG_ARRAYTYPE_P(8);          ArrayType       *attr_arr = PG_GETARG_ARRAYTYPE_P(_arg_attr_array);
379          Oid             attr_element_type = ARR_ELEMTYPE(attr_arr);          Oid             attr_element_type = ARR_ELEMTYPE(attr_arr);
380          int             attr_ndims = ARR_NDIM(attr_arr);          int             attr_ndims = ARR_NDIM(attr_arr);
381          int             *attr_dim_counts = ARR_DIMS(attr_arr);          int             *attr_dim_counts = ARR_DIMS(attr_arr);
# Line 385  Datum pgest_node(PG_FUNCTION_ARGS) Line 402  Datum pgest_node(PG_FUNCTION_ARGS)
402          ESTCOND *cond;          ESTCOND *cond;
403          ESTNODERES *nres;          ESTNODERES *nres;
404          ESTRESDOC *rdoc;          ESTRESDOC *rdoc;
405          const CBLIST *texts;          CBMAP *hints;
406          int resnum = 0;          int resnum = 0;
407          int limit = 0;          int limit = 0;
408          int offset = 0;          int offset = 0;
409            int depth = 0;
410    
411          char            *node_url;          char            *node_url;
412          char            *user, *passwd;          char            *user, *passwd;
# Line 448  Datum pgest_node(PG_FUNCTION_ARGS) Line 466  Datum pgest_node(PG_FUNCTION_ARGS)
466          /* take rest of arguments from function */          /* take rest of arguments from function */
467    
468          /* node URL */          /* node URL */
469          if (PG_ARGISNULL(0)) {          if (PG_ARGISNULL(_arg_node_uri)) {
470                  ereport(ERROR,                  ereport(ERROR,
471                                  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),                                  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
472                                   errmsg("node URL can't be null"),                                   errmsg("node URL can't be null"),
473                                   errdetail("Node URL must be valid URL to HyperEstraier node")));                                   errdetail("Node URL must be valid URL to HyperEstraier node")));
474          }          }
475          node_url = _textout(PG_GETARG_TEXT_P(0));          node_url = _textout(PG_GETARG_TEXT_P(_arg_node_uri));
476    
477          /* login and password */          /* login and password */
478          if (PG_ARGISNULL(1) || PG_ARGISNULL(2)) {          if (PG_ARGISNULL(_arg_login) || PG_ARGISNULL(_arg_passwd)) {
479                  ereport(ERROR,                  ereport(ERROR,
480                                  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),                                  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
481                                   errmsg("username and password can't be NULL"),                                   errmsg("username and password can't be NULL"),
482                                   errdetail("You must specify valid username and password to HyperEstraier node")));                                   errdetail("You must specify valid username and password to HyperEstraier node")));
483          }          }
484          user = _textout(PG_GETARG_TEXT_P(1));          user = _textout(PG_GETARG_TEXT_P(_arg_login));
485          passwd = _textout(PG_GETARG_TEXT_P(2));          passwd = _textout(PG_GETARG_TEXT_P(_arg_passwd));
486    
487            /* depth of search */
488            if (PG_ARGISNULL(_arg_depth)) {
489                    depth = 0;
490            } else {
491                    depth = PG_GETARG_INT32(_arg_depth);
492            }
493    
494          /* query string */          /* query string */
495          if (PG_ARGISNULL(3)) {          if (PG_ARGISNULL(_arg_query)) {
496                  query = "";                  query = "";
497          } else {          } else {
498                  query = _textout(PG_GETARG_TEXT_P(3));                  query = _textout(PG_GETARG_TEXT_P(_arg_query));
499          }          }
500    
501          /* atribute filter */          /* atribute filter */
502          if (PG_ARGISNULL(4)) {          if (PG_ARGISNULL(_arg_attr)) {
503                  attr = "";                  attr = "";
504          } else {          } else {
505                  attr = _textout(PG_GETARG_TEXT_P(4));                  attr = _textout(PG_GETARG_TEXT_P(_arg_attr));
506          }          }
507                    
508          /* sort order */          /* sort order */
509          if (PG_ARGISNULL(5)) {          if (PG_ARGISNULL(_arg_order)) {
510                  order = "";                  order = "";
511          } else {          } else {
512                  order = _textout(PG_GETARG_TEXT_P(5));                  order = _textout(PG_GETARG_TEXT_P(_arg_order));
513          }          }
514    
515    
516          /* limit */          /* limit */
517          if (PG_ARGISNULL(6)) {          if (PG_ARGISNULL(_arg_limit)) {
518                  limit = 0;                  limit = 0;
519          } else {          } else {
520                  limit = PG_GETARG_INT32(6);                  limit = PG_GETARG_INT32(_arg_limit);
521          }          }
522    
523          /* offset */          /* offset */
524          if (PG_ARGISNULL(7)) {          if (PG_ARGISNULL(_arg_offset)) {
525                  offset = 0;                  offset = 0;
526          } else {          } else {
527                  offset = PG_GETARG_INT32(7);                  offset = PG_GETARG_INT32(_arg_offset);
528          }          }
529    
530          /* initialize the network environment */          /* initialize the network environment */
# Line 513  Datum pgest_node(PG_FUNCTION_ARGS) Line 538  Datum pgest_node(PG_FUNCTION_ARGS)
538          node = est_node_new(node_url);          node = est_node_new(node_url);
539          est_node_set_auth(node, user, passwd);          est_node_set_auth(node, user, passwd);
540    
541          elog(DEBUG1, "pgest_node: query[%s] attr[%s] limit %d offset %d", query, (PG_ARGISNULL(4) ? "NULL" : attr), limit, offset);          elog(DEBUG1, "pgest_node: node: %s (d:%d) query[%s] attr[%s] limit %d offset %d", node_url, depth, query, (PG_ARGISNULL(_arg_attr) ? "NULL" : attr), limit, offset);
542                    
543          /* create a search condition object */          /* create a search condition object */
544          if (!(cond = est_cond_new())) {          if (!(cond = est_cond_new())) {
# Line 522  Datum pgest_node(PG_FUNCTION_ARGS) Line 547  Datum pgest_node(PG_FUNCTION_ARGS)
547          }          }
548                    
549          /* set the search phrase to the search condition object */          /* set the search phrase to the search condition object */
550          if (! PG_ARGISNULL(3) && strlen(query) > 0)          if (! PG_ARGISNULL(_arg_query) && strlen(query) > 0)
551                  est_cond_set_phrase(cond, query);                  est_cond_set_phrase(cond, query);
552    
553          /* minimum valid attribute length is 10: @a STREQ a */          /* minimum valid attribute length is 10: @a STREQ a */
554          if (! PG_ARGISNULL(4) && strlen(attr) >= 10) {          if (! PG_ARGISNULL(_arg_attr) && strlen(attr) >= 10) {
555                  elog(DEBUG1,"attributes: %s", attr);                  elog(DEBUG1,"attributes: %s", attr);
556                  char *curr_attr;                  cond_add_attr(cond, attr);
                 curr_attr = strtok(attr, ATTR_DELIMITER);  
                 while (curr_attr) {  
                         elog(DEBUG1,"est_cond_add_attr(%s)", curr_attr);  
                         est_cond_add_attr(cond, curr_attr);  
                         curr_attr = strtok(NULL, ATTR_DELIMITER);  
                 }  
557          }          }
558    
559          /* set the search phrase to the search condition object */          /* set the search phrase to the search condition object */
560          if (! PG_ARGISNULL(5) && strlen(order) > 0) {          if (! PG_ARGISNULL(_arg_order) && strlen(order) > 0) {
561                  elog(DEBUG1,"est_cond_set_order(%s)", order);                  elog(DEBUG1,"est_cond_set_order(%s)", order);
562                  est_cond_set_order(cond, order);                  est_cond_set_order(cond, order);
563          }          }
# Line 548  Datum pgest_node(PG_FUNCTION_ARGS) Line 567  Datum pgest_node(PG_FUNCTION_ARGS)
567                  est_cond_set_max(cond, limit + offset);                  est_cond_set_max(cond, limit + offset);
568          }          }
569    
570            if (offset) {
571                    elog(DEBUG1,"est_cond_set_skip(%d)", offset);
572                    est_cond_set_skip(cond, offset);
573            }
574    
575          /* get the result of search */          /* get the result of search */
576          /* FIXME: allow user to specify depath of search */          nres = est_node_search(node, cond, depth);
         nres = est_node_search(node, cond, 0);  
577    
578          if (! nres) {          if (! nres) {
579                  int status = est_node_status(node);                  int status = est_node_status(node);
# Line 573  Datum pgest_node(PG_FUNCTION_ARGS) Line 596  Datum pgest_node(PG_FUNCTION_ARGS)
596          if (limit && limit < resnum) {          if (limit && limit < resnum) {
597                  nrows = limit;                  nrows = limit;
598          } else {          } else {
599                  nrows = resnum - offset;                  nrows = resnum;
600          }          }
601    
602            /* get hints */
603            hints = est_noderes_hints(nres);
604    
605          elog(DEBUG1, "pgest_node: found %d hits for %s", resnum, query);          elog(DEBUG1, "pgest_node: found %d hits for %s", resnum, query);
606    
# Line 586  Datum pgest_node(PG_FUNCTION_ARGS) Line 611  Datum pgest_node(PG_FUNCTION_ARGS)
611          {          {
612    
613                  /* get result from estraier */                  /* get result from estraier */
614                  if (! ( rdoc = est_noderes_get_doc(nres, i + offset) )) {                  if (! ( rdoc = est_noderes_get_doc(nres, i) )) {
615                          elog(INFO, "can't find result %d", i + offset);                          elog(INFO, "pgest_node: can't find result %d", i + offset);
616                  } else {                  } else {
617                          elog(DEBUG1, "URI: %s\n Title: %s\n",                          elog(DEBUG1, "URI: %s\n Title: %s\n",
618                                  est_resdoc_attr(rdoc, "@uri"),                                  est_resdoc_attr(rdoc, "@uri"),
# Line 599  Datum pgest_node(PG_FUNCTION_ARGS) Line 624  Datum pgest_node(PG_FUNCTION_ARGS)
624                  for (j = 0; j < ncols; j++)                  for (j = 0; j < ncols; j++)
625                  {                  {
626                          bool    isnull;                          bool    isnull;
627                            char    *attr;  /* current attribute name */
628                            char    *hint;  /* position of current hint in attribute */
629                            char    *hint_val;
630    
631                          /* array value of this position */                          /* array value of this position */
632                          indx[0] = j + attr_dim_lower_bounds[0];                          indx[0] = j + attr_dim_lower_bounds[0];
633    
634                          dvalue = array_ref(attr_arr, attr_ndims, indx, -1, attr_len, attr_byval, attr_align, &isnull);                          dvalue = array_ref(attr_arr, attr_ndims, indx, -1, attr_len, attr_byval, attr_align, &isnull);
635                            attr = (char *)DirectFunctionCall1(textout, dvalue);
636    
637                          if (!isnull && rdoc)                          if (!isnull && (hint = strstr(attr, HINTS_PREFIX)) != NULL) {
638                                  values[j] = DatumGetCString(                                  /* skip HINTS. prefix */
639                                          node_attr2text(rdoc,                                  hint += strlen(HINTS_PREFIX);
640                                                  (char *)DirectFunctionCall1(textout, dvalue)  
641                                          ));                                  hint_val = (char *)cbmapget(hints, hint, -1, NULL);
642                                    elog(DEBUG2, "hint %s = %s", hint, hint_val);
643    
644                                    if (hint_val != NULL) {
645                                            values[j] = DatumGetCString( hint_val );
646                                    } else {
647                                            elog(INFO, "can't get hint in results: %s", hint);
648                                            values[j] = NULL;
649                                    }
650                            } else if (!isnull && rdoc)
651                                    values[j] = DatumGetCString( node_attr2text(rdoc, attr) );
652                          else                          else
653                                  values[j] = NULL;                                  values[j] = NULL;
654                  }                  }
# Line 656  char *node_attr2text(ESTRESDOC *rdoc, ch Line 695  char *node_attr2text(ESTRESDOC *rdoc, ch
695          int len;          int len;
696          int attrlen;          int attrlen;
697    
698          elog(DEBUG1, "doc: %08x, attr: %s", rdoc, attr);          if (! rdoc) return (Datum) NULL;
699    
700            elog(DEBUG1, "doc: %p, attr: %s", rdoc, attr);
701    
702          if ( (attrval = est_resdoc_attr(rdoc, attr)) && (attrlen = strlen(attrval)) ) {          if ( (attrval = est_resdoc_attr(rdoc, attr)) && (attrlen = strlen(attrval)) ) {
703                  val = (char *) palloc(attrlen * sizeof(char));                  val = (char *) palloc(attrlen * sizeof(char));
# Line 682  char *node_attr2text(ESTRESDOC *rdoc, ch Line 723  char *node_attr2text(ESTRESDOC *rdoc, ch
723          return val;          return val;
724  }  }
725    
726    /* parse attributes and add them to confition */
727    void cond_add_attr(ESTCOND *cond, char *attr) {
728            char *next;
729            char *curr_attr;
730            while ( strlen(attr) > 0 ) {
731                    printf("len [%s] = %zd\n", attr, strlen(attr));
732                    if ((next = strstr(attr, ATTR_DELIMITER)) != NULL) {
733                            curr_attr = palloc( next - attr + 1 );
734                            memcpy(curr_attr, attr, next-attr);
735                            curr_attr[next-attr] = '\0';
736                            next += strlen(ATTR_DELIMITER);
737                    } else {
738                            next = "";
739                            curr_attr = attr;
740                    }
741                    elog(DEBUG1, "est_cond_add_attr(%s)", curr_attr);
742                    est_cond_add_attr(cond, curr_attr);
743                    attr = next;
744            }
745    }
746    
747    /* trigger to keep data in Hyper Estraier index up-to-date */
748    /* CREATE FUNCTION pgest_trigger() RETURNS TRIGGER AS ... */
749    
750    /*
751     * UPDATE, INSERT and DELETE triggers are like this:
752    
753    CREATE TRIGGER pgest_trigger_update AFTER UPDATE
754            ON table_name FOR EACH ROW
755            EXECUTE PROCEDURE pgest_trigger('http://localhost:1978/node/trivia','admin','admin',
756                    'name_of_pk', 'column', 'another_column', 'and_so_on'
757            )
758    
759    */
760    
761    PG_FUNCTION_INFO_V1(pgest_trigger);
762    Datum pgest_trigger(PG_FUNCTION_ARGS) {
763    
764            TriggerData *data;
765            TupleDesc   tupdesc;
766            HeapTuple   ret;
767    
768            char **args;
769            char *keycol  = NULL;
770            char *key     = NULL;
771            char *col_data = NULL;
772            int   knumber;
773            int   i;
774            int   create_doc = 0;
775            int   edit_doc = 0;
776    
777            ESTNODE *node;
778            ESTDOC *doc;
779    
780    
781    
782            if (! CALLED_AS_TRIGGER(fcinfo)) {
783                    elog(ERROR, "pgest_trigger() must be called as a trigger");
784            }
785    
786            data = (TriggerData *) fcinfo->context;
787    
788            if (data->tg_trigger->tgnargs < 5)
789                    elog(ERROR, "pgest_trigger() requires at least 5 parameters ('http://localhost:1978/node/trivia', 'user', 'passwd', 'pk_column', 'column', ... )");
790    
791            args       = data->tg_trigger->tgargs;
792            keycol     = args[3];
793    
794            tupdesc = data->tg_relation->rd_att;
795    
796            knumber = SPI_fnumber(tupdesc, keycol);
797            key = SPI_getvalue(data->tg_trigtuple, tupdesc, knumber);
798    
799    
800            /* initialize the network environment */
801            if( ! est_init_net_env() )
802                    elog(ERROR, "pgest_trigger: network is unavailable\n");
803    
804            /* create and configure the node connection object */
805            node = est_node_new( args[0] );
806            est_node_set_auth(node, args[1], args[2]);
807    
808    
809            if (TRIGGER_FIRED_BY_INSERT(data->tg_event)) {
810                    /* There is no old data */
811                    ret = data->tg_trigtuple;
812    
813                    create_doc++;
814    
815            } else if (TRIGGER_FIRED_BY_UPDATE(data->tg_event)) {
816                    ret = data->tg_newtuple;
817    
818                    edit_doc++;
819    
820            } else if (TRIGGER_FIRED_BY_DELETE(data->tg_event)) {
821                    /* There is no new data */
822                    ret = data->tg_trigtuple;
823    
824                    if (! est_node_out_doc_by_uri(node, key) )
825                            elog(ERROR, "est_node_doc_by_uri(%s): %d\n", key, est_node_status(node));
826    
827            } else {
828                    elog(ERROR, "pgest_trigger() not called from INSERT/UPDATE/DELETE");
829            }
830    
831            if ( create_doc || edit_doc ) {
832    
833                    if ( create_doc ) {
834                            /* create a document object */
835                            doc = est_doc_new();
836                            est_doc_add_attr(doc, "@uri", key);
837    
838                            elog(DEBUG1, "est_doc_new @uri=%s", key);
839                    } else {
840                            /* edit existing document */
841                            doc = est_node_get_doc_by_uri(node, key);
842                            if (doc == NULL)
843                                    elog(ERROR, "est_node_get_doc_by_uri(%s): %d\n", key, est_node_status(node));
844                            elog(DEBUG1, "est_node_get_doc_by_uri(%s)", key);
845                    }
846    
847                    for( i = 4; i < data->tg_trigger->tgnargs; i++ ) {
848    
849                            col_data = SPI_getvalue(ret, tupdesc, SPI_fnumber(tupdesc, args[i]));
850    
851                            if (data) {
852                                    elog(DEBUG1, " + %s = %s", args[i], col_data);
853                                    est_doc_add_attr(doc, args[i], col_data);
854                                    est_doc_add_text(doc, col_data);
855                            }
856    
857                    }
858    
859                    if ( edit_doc ) {
860                            /* update existing document */
861                            if( ! est_node_edit_doc(node, doc) )
862                                    elog(ERROR, "est_node_edit_doc: %d\n", est_node_status(node));
863                    } else {
864                            /* register the document object to the node */
865                            if( ! est_node_put_doc(node, doc) )
866                                    elog(ERROR, "est_node_put_doc: %d\n", est_node_status(node));
867                    }
868    
869                    /* destroy the document object */
870                    est_doc_delete(doc);
871    
872            }
873    
874            /* destroy the node object */
875            est_node_delete(node);
876            /* free the networking environment */
877            est_free_net_env();
878    
879    
880            return PointerGetDatum(ret);
881    }
882    

Legend:
Removed from v.44  
changed lines
  Added in v.85

  ViewVC Help
Powered by ViewVC 1.1.26