Uploaded image for project: 'Couchbase Server'
  1. Couchbase Server
  2. MB-50453

[n1ql+fts] Possible issue while passing in an array as an argument to a UDF

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Major
    • 7.1.0
    • 7.1.0
    • fts
    • None
    • Untriaged
    • 1
    • Unknown

    Description

      Start by setting up a default FTS index definition over `travel-sample` (no frills).

      curl -XPUT -H Content-type:application/json -u Administrator:password http://127.0.0.1:8094/api/index/travel -d '{
       "name": "travel",
       "type": "fulltext-index",
       "params": {
        "doc_config": {
         "docid_prefix_delim": "",
         "docid_regexp": "",
         "mode": "type_field",
         "type_field": "type"
        },
        "mapping": {
         "default_analyzer": "standard",
         "default_datetime_parser": "dateTimeOptional",
         "default_field": "_all",
         "default_mapping": {
          "default_analyzer": "keyword",
          "dynamic": true,
          "enabled": true
         },
         "default_type": "_default",
         "docvalues_dynamic": false,
         "index_dynamic": true,
         "store_dynamic": false,
         "type_field": "_type"
        },
        "store": {
         "indexType": "scorch",
         "segmentVersion": 15
        }
       },
       "sourceType": "gocbcore",
       "sourceName": "travel-sample",
       "sourceUUID": "",
       "sourceParams": {},
       "planParams": {
        "maxPartitionsPerPIndex": 1024,
        "indexPartitions": 1,
        "numReplicas": 0
       },
       "uuid": ""
      }' 

      Then define a JS function ..

      function argsselectclause(typename, rowlimit) {
              var iter = select * from `travel-sample` USE INDEX (USING FTS) where type in $typename limit $rowlimit;
              let acc = [];
              for (const row of iter) {
                      acc.push(row);
              }
              return {'num_entries': acc.length, 'data': acc};     
      }    

      , and then set up a UDF over it called selectfts1.

      Now when I execute the following query ..

      EXECUTE FUNCTION selectfts1(["airline"], 3) 

      , I see a failure ..

      [
        {
          "code": 10109,
          "msg": "Error executing function selectfts1 (n1qlfts1:argsselectclause): Evaluator error Exceptions from JS code : run argsselectclause failed:\nException: Error: No index available on keyspace `default`:`travel-sample` that matches your query. Use CREATE PRIMARY INDEX ON `default`:`travel-sample` to create a primary index, or check that your expected index is online.\nLocation: functions/n1qlfts1.js:2 \nCode:         var iter = N1QL('select * from `travel-sample` t USE INDEX (USING FTS) where t.type in $typename limit $rowlimit;', {'rowlimit':rowlimit, 'typename':typename}, true);\nError\n    at argsselectclause (functions/n1qlfts1.js:2:20)\n - cause: Evaluator error Exceptions from JS code : run argsselectclause failed:\nException: Error: No index available on keyspace `default`:`travel-sample` that matches your query. Use CREATE PRIMARY INDEX ON `default`:`travel-sample` to create a primary index, or check that your expected index is online.\nLocation: functions/n1qlfts1.js:2 \nCode:         var iter = N1QL('select * from `travel-sample` t USE INDEX (USING FTS) where t.type in $typename limit $rowlimit;', {'rowlimit':rowlimit, 'typename':typename}, true);\nError\n    at argsselectclause (functions/n1qlfts1.js:2:20)\n"
        }
      ] 

      I changed the JS function a bit to ..

      function argsselectclause(typename, rowlimit) {
              var iter = select * from `travel-sample` t USE INDEX (USING FTS) where t.type in [$typename] limit $rowlimit;
              let acc = [];
              for (const row of iter) {
                      acc.push(row);
              }
              return {'num_entries': acc.length, 'data': acc};
           
      }    

      Notice that the function now expects a string instead of an array of strings. I changed the query to ..

      EXECUTE FUNCTION selectfts1("airline", 3) 

      .. and now the query executes just fine.

      So it seems - that the function is only able to interpret simple data types (string, number, etc.) but not objects/arrays.

      Let me know if I'm missing something obvious here.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            pierre.regazzoni Pierre Regazzoni
            abhinav Abhi Dangeti
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes

                PagerDuty