1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #include "view-priv.h"
28 
29 #include <klib/symbol.h>
30 #include <kfs/dyload.h>
31 #include <bitstr.h>
32 
33 typedef struct VViewCursor VViewCursor;
34 #define VCURSOR_IMPL VViewCursor
35 #include "cursor-struct.h"
36 
37 #include "column-priv.h"
38 #include "schema-priv.h"
39 #include "table-priv.h"
40 #include "phys-priv.h"
41 #include "prod-priv.h"
42 #include "linker-priv.h"
43 #include "schema-parse.h"
44 #include "prod-expr.h"
45 
46 #include <sysalloc.h>
47 #include <stdio.h>
48 
49 struct VViewCursor
50 {
51     VCursor dad;
52 
53     /* attached reference to view */
54     const VView * view;
55 };
56 
57 static rc_t VViewCursorWhack ( const VViewCursor * p_self );
58 static rc_t VViewCursorVAddColumn ( const VViewCursor *cself, uint32_t *idx, const char *name, va_list args );
59 static rc_t VViewCursorVGetColumnIdx ( const VViewCursor *self, uint32_t *idx, const char *name, va_list args );
60 static rc_t VViewCursorOpen ( const VViewCursor * p_self );
61 
62 static rc_t VViewCursorMakeColumn ( VViewCursor *self, VColumn **col, const SColumn *scol, Vector *cx_bind );
63 static const struct VTable * VViewCursorGetTable ( const VViewCursor * self );
64 static bool VViewCursorIsReadOnly ( const VViewCursor * self );
65 static const struct VSchema * VViewCursorGetSchema ( const VViewCursor * p_self );
66 static VBlobMRUCache * VViewCursorGetBlobMruCache ( struct VViewCursor * p_self );
67 static uint32_t VViewCursorIncrementPhysicalProductionCount ( struct VViewCursor * p_self );
68 static rc_t VViewCursorSetRowId ( const VViewCursor * p_self, int64_t p_id );
69 static rc_t VViewCursorOpenRow ( const VViewCursor *cself );
70 
71 static rc_t VViewCursorWrite ( VViewCursor *self, uint32_t col_idx, bitsz_t elem_bits, const void *buffer, bitsz_t boff, uint64_t count );
72 static rc_t VViewCursorCommitRow ( VViewCursor *self );
73 static rc_t VViewCursorRepeatRow ( VViewCursor *self, uint64_t count );
74 static rc_t VViewCursorFlushPage ( VViewCursor *self );
75 static rc_t VViewCursorDefault ( VViewCursor *self, uint32_t col_idx, bitsz_t elem_bits, const void *buffer, bitsz_t boff, uint64_t row_len );
76 static rc_t VViewCursorCommit ( VViewCursor *self );
77 static rc_t VViewCursorOpenParentUpdate ( VViewCursor *self, VTable **tbl );
78 static rc_t VViewCursorCloseRow ( const VViewCursor *cself );
79 static rc_t VViewCursorGetBlob ( const VViewCursor * p_self, const VBlob ** p_blob, uint32_t p_col_idx );
80 static rc_t VViewCursorGetBlobDirect ( const VViewCursor *self, const VBlob **blob, int64_t row_id, uint32_t col_idx );
81 static rc_t VViewCursorRead ( const VViewCursor *self, uint32_t col_idx,
82     uint32_t elem_bits, void *buffer, uint32_t blen, uint32_t *row_len );
83 static rc_t VViewCursorReadDirect ( const VViewCursor *self, int64_t row_id, uint32_t col_idx,
84     uint32_t elem_bits, void *buffer, uint32_t blen, uint32_t *row_len );
85 static rc_t VViewCursorReadBits ( const VViewCursor * p_self, uint32_t p_col_idx, uint32_t p_elem_bits, uint32_t p_start, void * p_buffer, uint32_t p_off, uint32_t p_blen, uint32_t * p_num_read, uint32_t * p_remaining );
86 static rc_t VViewCursorReadBitsDirect ( const VViewCursor * p_self, int64_t p_row_id, uint32_t p_col_idx, uint32_t p_elem_bits, uint32_t p_start, void * p_buffer, uint32_t p_off, uint32_t p_blen, uint32_t * p_num_read, uint32_t * p_remaining );
87 static rc_t VViewCursorCellData ( const VViewCursor *self, uint32_t col_idx, uint32_t *elem_bits, const void **base, uint32_t *boff, uint32_t *row_len );
88 static rc_t VViewCursorCellDataDirect ( const VViewCursor *self, int64_t row_id, uint32_t col_idx,
89     uint32_t *elem_bits, const void **base, uint32_t *boff, uint32_t *row_len );
90 static rc_t VViewCursorDataPrefetch ( const VViewCursor *cself, const int64_t *row_ids, uint32_t col_idx, uint32_t num_rows, int64_t min_valid_row_id, int64_t max_valid_row_id, bool continue_on_error );
91 static rc_t VViewCursorOpenParentRead ( const VViewCursor * p_self, const VTable ** p_tbl );
92 
93 static rc_t VViewCursorPermitPostOpenAdd ( const VViewCursor * self );
94 static rc_t VViewCursorSuspendTriggers ( const VViewCursor * self );
95 static rc_t VViewCursorLinkedCursorGet ( const VViewCursor *cself,const char *tbl, struct VCursor const **curs);
96 static rc_t VViewCursorLinkedCursorSet ( const VViewCursor *cself,const char *tbl, struct VCursor const *curs);
97 static uint64_t VViewCursorSetCacheCapacity ( VViewCursor *self,uint64_t capacity);
98 static uint64_t VViewCursorGetCacheCapacity ( const VViewCursor *self);
99 
100 static const KSymbol * VViewCursorFindOverride ( const VViewCursor * p_self, const struct VCtxId * p_cid );
101 
102 static rc_t VViewCursorLaunchPagemapThread ( struct VViewCursor *self );
103 static const PageMapProcessRequest* VViewCursorPageMapProcessRequest ( const struct VViewCursor *self );
104 static bool VViewCursorCacheActive ( const struct VViewCursor * self, int64_t * cache_empty_end );
105 static rc_t VViewCursorInstallTrigger ( struct VViewCursor * self, struct VProduction * prod );
106 
107 static VCursor_vt VViewCursor_vt =
108 {
109     VViewCursorWhack,
110     VViewCursorVAddColumn,
111     VViewCursorVGetColumnIdx,
112     VViewCursorOpen,
113     VViewCursorSetRowId,
114     VViewCursorOpenRow,
115     VViewCursorWrite,
116     VViewCursorCommitRow,
117     VViewCursorCloseRow,
118     VViewCursorRepeatRow,
119     VViewCursorFlushPage,
120     VViewCursorGetBlob,
121     VViewCursorGetBlobDirect,
122     VViewCursorRead,
123     VViewCursorReadDirect,
124     VViewCursorReadBits,
125     VViewCursorReadBitsDirect,
126     VViewCursorCellData,
127     VViewCursorCellDataDirect,
128     VViewCursorDataPrefetch,
129     VViewCursorDefault,
130     VViewCursorCommit,
131     VViewCursorOpenParentRead,
132     VViewCursorOpenParentUpdate,
133     VViewCursorPermitPostOpenAdd,
134     VViewCursorSuspendTriggers,
135     VViewCursorGetSchema,
136     VViewCursorLinkedCursorGet,
137     VViewCursorLinkedCursorSet,
138     VViewCursorSetCacheCapacity,
139     VViewCursorGetCacheCapacity,
140     VViewCursorMakeColumn,
141     VViewCursorGetTable,
142     VViewCursorIsReadOnly,
143     VViewCursorGetBlobMruCache,
144     VViewCursorIncrementPhysicalProductionCount,
145     VViewCursorFindOverride,
146     VViewCursorLaunchPagemapThread,
147     VViewCursorPageMapProcessRequest,
148     VViewCursorCacheActive,
149     VViewCursorInstallTrigger
150 };
151 
152 // VViewCursor
153 
154 rc_t
VViewCursorMake(const VView * p_view,VViewCursor ** p_curs)155 VViewCursorMake ( const VView * p_view, VViewCursor ** p_curs )
156 {
157     rc_t rc;
158     VViewCursor * curs = calloc ( 1, sizeof * curs );
159     if ( curs == NULL )
160     {
161         rc = RC ( rcVDB, rcCursor, rcConstructing, rcMemory, rcExhausted );
162     }
163     else
164     {
165         rc = VViewAddRef ( p_view );
166         if ( rc == 0 )
167         {
168             curs -> dad . vt = & VViewCursor_vt;
169             curs -> view = p_view;
170             VectorInit ( & curs -> dad . row, 1, 16 );
171             VCursorCacheInit ( & curs -> dad . col, 0, 16 );
172             VCursorCacheInit ( & curs -> dad . phys, 0, 16 );
173             VCursorCacheInit ( & curs -> dad . prod, 0, 16 );
174             VectorInit ( & curs -> dad . owned, 0, 64 );
175             KRefcountInit ( & curs -> dad . refcount, 1, "VViewCursor", "make", "vcurs" );
176             curs -> dad . state = vcConstruct;
177             * p_curs = curs;
178             return 0;
179         }
180         free ( curs );
181     }
182     return rc;
183 }
184 
185 rc_t
VViewCursorWhack(const VViewCursor * p_self)186 VViewCursorWhack ( const VViewCursor * p_self )
187 {
188     VViewCursor * self = ( VViewCursor * ) p_self;
189     VViewRelease ( self -> view );
190     return VCursorWhackInt ( & self -> dad );
191 }
192 
193 /* AddSColumn
194  */
195 static
196 rc_t
VViewCursorAddSColumn(VViewCursor * p_self,uint32_t * p_idx,const SColumn * p_scol,const VTypedecl * p_cast,Vector * p_cx_bind)197 VViewCursorAddSColumn ( VViewCursor *      p_self,
198                         uint32_t *         p_idx,
199                         const SColumn *    p_scol,
200                         const VTypedecl *  p_cast,
201                         Vector *           p_cx_bind )
202 {
203     rc_t rc = 0;
204     VColumn *col;
205 
206     /* must be readable */
207     if ( p_scol -> read == NULL )
208     {
209         return RC ( rcVDB, rcCursor, rcUpdating, rcColumn, rcWriteonly );
210     }
211 
212     /* must not already be there - benign error */
213     col = VCursorCacheGet ( & p_self -> dad . col, & p_scol -> cid );
214     if ( col != NULL )
215     {
216         * p_idx = col -> ord;
217         rc = RC ( rcVDB, rcCursor, rcUpdating, rcColumn, rcExists );
218     }
219     else
220     {
221         /* make object */
222         rc = VColumnMake ( & col, p_self -> view -> schema, p_scol );
223         if ( rc == 0 )
224         {
225 #if 0
226             /* open column if cursor open or type unknown */
227             if ( self -> dad . state >= vcReady || scol -> td . type_id == 0 )
228             {
229                 rc = RC ( rcVDB, rcCursor, rcUpdating, rcColumn, ?? );
230             }
231             else
232             {   /* check cast of SColumn against requested type
233                 this is to handle the case where the column
234                 was created incomplete, i.e. with unknown type */
235                 if ( cast != NULL && | VTypedeclToTypedecl ( & scol -> td,
236                         self -> schema, cast, & col -> td, NULL ) )
237                 {
238                     rc = RC ( rcVDB, rcCursor, rcUpdating, rcColumn, ?? );
239                 }
240             }
241 #endif
242 
243             if ( rc == 0 )
244             {
245                 /* insert it into vectors */
246                 rc = VectorAppend ( & p_self -> dad . row, & col -> ord, col );
247                 if ( rc == 0 )
248                 {
249                     void * ignore;
250                     rc = VCursorCacheSet ( & p_self -> dad . col, & p_scol -> cid, col );
251                     if ( rc == 0 )
252                     {
253                         * p_idx = col -> ord;
254                         return 0;
255                     }
256                     VectorSwap ( & p_self -> dad . row, col -> ord, NULL, & ignore );
257                 }
258             }
259             VColumnWhack ( col, NULL );
260         }
261     }
262 
263     return rc;
264 }
265 
266 /* AddColspec
267  *  a "colspec" is either a simple column name or a typed name expression
268  *  uses STable to evaluate colspec and find an SColumn
269  */
270 static
271 rc_t
VViewCursorAddColspec(VViewCursor * p_self,uint32_t * p_idx,const char * p_colspec)272 VViewCursorAddColspec ( VViewCursor * p_self, uint32_t * p_idx, const char * p_colspec )
273 {
274     rc_t rc = 0;
275 
276     /* find an appropriate column in schema */
277     uint32_t type;
278     VTypedecl cast;
279     const SNameOverload *name;
280     const SColumn *scol = SViewFind ( p_self -> view -> sview,
281                                       p_self -> view -> schema,
282                                       & cast,
283                                       & name,
284                                       & type,
285                                       p_colspec,
286                                       "VViewCursorAddColspec",
287                                       true );
288     if ( scol == NULL || type != eColumn )
289     {
290         rc = SILENT_RC ( rcVDB, rcCursor, rcUpdating, rcColumn, rcNotFound );
291     }
292     else
293     {
294         Vector cx_bind;
295         VectorInit ( & cx_bind, 1, p_self -> view -> schema -> num_indirect );
296         rc = VViewCursorAddSColumn ( p_self, p_idx, scol, & cast, & cx_bind );
297         VectorWhack ( & cx_bind, NULL, NULL );
298     }
299 
300     return rc;
301 }
302 
303 rc_t
VViewCursorVAddColumn(const VViewCursor * p_self,uint32_t * p_idx,const char * p_name,va_list p_args)304 VViewCursorVAddColumn ( const VViewCursor * p_self,
305                         uint32_t *          p_idx,
306                         const char *        p_name,
307                         va_list             p_args )
308 {
309     rc_t rc = 0;
310     if ( p_idx == NULL )
311     {
312         rc = RC ( rcVDB, rcCursor, rcUpdating, rcParam, rcNull );
313     }
314     else if ( p_name == NULL )
315     {
316         rc = RC ( rcVDB, rcCursor, rcUpdating, rcName, rcNull );
317     }
318     else if ( p_name [ 0 ] == 0 )
319     {
320         rc = RC ( rcVDB, rcCursor, rcUpdating, rcName, rcEmpty );
321     }
322     else if ( p_self -> dad . state != vcConstruct )
323     {
324         rc = RC ( rcVDB, rcCursor, rcUpdating, rcCursor, rcLocked );
325     }
326     else
327     {
328         char colspec [ 1024 ];
329         int len = vsnprintf ( colspec, sizeof colspec, p_name, p_args );
330         if ( len < 0 || len >= sizeof colspec )
331         {
332             rc = RC ( rcVDB, rcCursor, rcUpdating, rcName, rcExcessive );
333         }
334         else
335         {
336             * p_idx = 0;
337             rc = VViewCursorAddColspec ( ( VViewCursor * ) p_self, p_idx, colspec );
338         }
339     }
340     return rc;
341 }
342 
343 /* GetColumnIdx
344  *  retrieve column index by name spec
345  *
346  *  "idx" [ OUT ] - return parameter for column index
347  *
348  *  "name" [ IN ] - NUL terminated column name spec.
349  */
350 rc_t
VViewCursorVGetColumnIdx(const VViewCursor * p_self,uint32_t * p_idx,const char * p_name,va_list args)351 VViewCursorVGetColumnIdx ( const VViewCursor * p_self,
352                            uint32_t *           p_idx,
353                            const char *         p_name,
354                            va_list args )
355 {
356     rc_t rc;
357 
358     if ( p_idx == NULL )
359     {
360         rc = RC ( rcVDB, rcCursor, rcAccessing, rcParam, rcNull );
361     }
362     else
363     {
364         * p_idx = 0;
365 
366         if ( p_name == NULL )
367         {
368             rc = RC ( rcVDB, rcCursor, rcAccessing, rcName, rcNull );
369         }
370         else if ( p_name [ 0 ] == 0 )
371         {
372             rc = RC ( rcVDB, rcCursor, rcAccessing, rcName, rcEmpty );
373         }
374         else if ( p_self -> dad . state == vcFailed )
375         {
376             rc = RC ( rcVDB, rcCursor, rcAccessing, rcCursor, rcInvalid );
377         }
378         else
379         {
380             char colspec [ 1024 ];
381             int len = vsnprintf ( colspec, sizeof colspec, p_name, args );
382             if ( len < 0 || len >= sizeof colspec )
383             {
384                 rc = RC ( rcVDB, rcCursor, rcAccessing, rcName, rcExcessive );
385             }
386             else
387             {
388                 /* find an appropriate column in schema */
389                 uint32_t type;
390                 VTypedecl cast;
391                 const SNameOverload *name;
392                 const SColumn *scol = SViewFind ( p_self -> view -> sview,
393                                                 p_self -> view -> schema,
394                                                 & cast,
395                                                 & name,
396                                                 & type,
397                                                 colspec,
398                                                 "VViewCursorVGetColumnIdx",
399                                                 true );
400                 rc = VCursorGetColidx ( & p_self -> dad, scol, name, type, p_idx );
401             }
402         }
403     }
404 
405     return rc;
406 }
407 
408 typedef struct VProdResolveData VProdResolveData;
409 struct VProdResolveData
410 {
411     VProdResolve pr;
412     rc_t rc;
413 };
414 
415 static
416 bool CC
VViewCursorResolveColumn(void * item,void * data)417 VViewCursorResolveColumn ( void *item, void *data )
418 {
419     if ( item != NULL )
420     {
421         void *ignore;
422 
423         VColumn *col = item;
424         SColumn *scol = ( SColumn* ) col -> scol;
425         VProdResolveData *pb = data;
426         VViewCursor * self = (VViewCursor *) pb -> pr . curs;
427         VProduction * src = NULL;
428 
429         pb -> rc = VProdResolveColumnRoot ( & pb -> pr, & src, scol );
430         if ( pb -> rc == 0 )
431         {
432             if ( src > FAILED_PRODUCTION )
433             {
434                 /* repair for incomplete implicit column decl */
435                 if ( scol -> td . type_id == 0 )
436                     scol -> td = src -> fd . td;
437 
438                 return false;
439             }
440 
441             pb -> rc = RC ( rcVDB, rcCursor, rcOpening, rcColumn, rcUndefined );
442         }
443 
444         /* check for tolerance */
445         if ( ! pb -> pr . ignore_column_errors )
446         {
447             PLOGERR ( klogErr, ( klogErr, pb -> rc, "failed to resolve column '$(name)' idx '$(idx)'",
448                                     "name=%.*s,idx=%u"
449                                     , ( int ) scol -> name -> name . size
450                                     , scol -> name -> name . addr
451                                     , col -> ord ));
452             return true;
453         }
454 
455         /* remove from row and cache */
456         VectorSwap ( & self -> dad . row, col -> ord, NULL, & ignore );
457         VCursorCacheSwap ( & self -> dad . col, & scol -> cid, NULL, & ignore );
458 
459         /* dump the VColumn */
460         VColumnWhack ( col, NULL );
461 
462         /* return no-error */
463         pb -> rc = 0;
464     }
465 
466     return false;
467 }
468 
469 static
470 rc_t
VViewCursorResolveColumnProductions(VViewCursor * p_self,const struct KDlset * p_libs)471 VViewCursorResolveColumnProductions ( VViewCursor * p_self, const struct KDlset * p_libs )
472 {
473     Vector cx_bind;
474     VProdResolveData pb;
475     const VTable * tbl = VViewCursorGetTable ( p_self );
476 
477     pb . pr . schema    = p_self -> view -> schema;
478     pb . pr . ld        = tbl -> linker;
479     pb . pr . libs      = p_libs;
480     pb . pr . name      = & p_self -> view -> sview -> name -> name;
481     pb . pr . primary_table = tbl;
482     pb . pr . view      = p_self -> view;
483     pb . pr . curs      = ( VCursor * ) p_self;
484     pb . pr . cache     = & p_self -> dad . prod;
485     pb . pr . owned     = & p_self -> dad . owned;
486     pb . pr . cx_bind   = & cx_bind;
487 
488     pb . pr . chain     = chainDecoding;
489     pb . pr . blobbing  = false;
490     pb . pr . ignore_column_errors = false;
491     pb . pr . discover_writable_columns = false;
492     pb . rc = 0;
493 
494     VectorInit ( & cx_bind, 1, p_self -> view -> schema -> num_indirect );
495 
496     if ( ! VectorDoUntil ( & p_self -> dad . row, false, VViewCursorResolveColumn, & pb ) )
497     {
498         pb . rc = 0;
499     }
500 
501     VectorWhack ( & cx_bind, NULL, NULL );
502 
503     return pb . rc;
504 }
505 
506 static
507 rc_t
VViewCursorOpenRead(VViewCursor * p_self,const struct KDlset * p_libs)508 VViewCursorOpenRead ( VViewCursor * p_self, const struct KDlset * p_libs )
509 {
510     rc_t rc;
511 
512     if ( p_self -> dad . state >= vcReady )
513     {
514         rc = 0;
515     }
516     else if ( p_self -> dad . state == vcFailed )
517     {
518         rc = RC ( rcVDB, rcCursor, rcOpening, rcCursor, rcInvalid );
519     }
520     else
521     {
522         rc = VViewCursorResolveColumnProductions ( p_self, p_libs );
523         if ( rc == 0 )
524         {
525             p_self -> dad . row_id = p_self -> dad . start_id = p_self -> dad . end_id = 1;
526             p_self -> dad . state = vcReady;
527             return rc;
528         }
529         p_self -> dad . state = vcFailed;
530     }
531 
532     return rc;
533 }
534 
535 /* Open
536  *  open cursor, resolving schema
537  *  for the set of opened columns
538  *
539  *  NB - there is no corresponding "Close"
540  *  use "Release" instead.
541  */
542 rc_t
VViewCursorOpen(const VViewCursor * p_self)543 VViewCursorOpen ( const VViewCursor * p_self )
544 {
545     VViewCursor * self = ( VViewCursor * ) p_self;
546     struct KDlset *libs = 0;
547 
548     rc_t rc = VLinkerOpen ( self -> view -> linker, & libs );
549     if ( rc == 0 )
550     {
551         rc = VViewCursorOpenRead ( self, libs );
552         if ( rc == 0 )
553         {
554             int64_t first;
555             uint64_t count;
556 
557             rc = VCursorIdRange ( & p_self -> dad, 0, & first, & count );
558             if ( rc == 0 )
559             {
560                 if ( count != 0 )
561                 {
562                     /* set initial row id to starting row */
563                     self -> dad . start_id =
564                     self -> dad . end_id =
565                     self -> dad . row_id = first;
566                 }
567             }
568             else
569             {
570                 self -> dad . state = vcFailed;
571             }
572         }
573         KDlsetRelease ( libs );
574     }
575 
576     return rc;
577 }
578 
579 rc_t
VViewCursorMakeColumn(VViewCursor * p_self,VColumn ** p_col,const SColumn * p_scol,Vector * p_cx_bind)580 VViewCursorMakeColumn ( VViewCursor * p_self, VColumn ** p_col, const SColumn * p_scol, Vector * p_cx_bind )
581 {
582     return VColumnMake ( p_col, p_self -> view -> schema, p_scol );
583 }
584 
585 const VTable *
VViewCursorGetTable(const VViewCursor * p_self)586 VViewCursorGetTable ( const VViewCursor * p_self )
587 {
588     return VViewPrimaryTable ( p_self -> view );
589 }
590 
591 bool
VViewCursorIsReadOnly(const VViewCursor * p_self)592 VViewCursorIsReadOnly ( const VViewCursor * p_self )
593 {
594     return true;
595 }
596 
597 const struct VSchema *
VViewCursorGetSchema(const VViewCursor * p_self)598 VViewCursorGetSchema ( const VViewCursor * p_self )
599 {
600     return p_self -> view -> schema;
601 }
602 
603 VBlobMRUCache *
VViewCursorGetBlobMruCache(struct VViewCursor * p_self)604 VViewCursorGetBlobMruCache ( struct VViewCursor * p_self )
605 {   /* no blob cache for views, yet */
606     return NULL;
607 }
608 
609 uint32_t
VViewCursorIncrementPhysicalProductionCount(struct VViewCursor * p_self)610 VViewCursorIncrementPhysicalProductionCount ( struct VViewCursor * p_self )
611 {
612     return 0;
613 }
614 
615 rc_t
VViewCursorSetRowId(const VViewCursor * p_self,int64_t p_id)616 VViewCursorSetRowId ( const VViewCursor * p_self, int64_t p_id )
617 {
618     VViewCursor * self = ( VViewCursor * ) p_self;
619     return VCursorSetRowIdRead ( & self -> dad, p_id );
620 }
621 
622 rc_t
VViewCursorOpenRow(const VViewCursor * p_self)623 VViewCursorOpenRow ( const VViewCursor * p_self )
624 {
625     rc_t rc;
626     VViewCursor * self = ( VViewCursor * ) p_self;
627 
628     if ( self -> dad . state < vcReady )
629     {
630         rc = RC ( rcVDB, rcCursor, rcOpening, rcRow, rcIncomplete );
631     }
632     else if ( self -> dad . state > vcReady )
633     {   /* ignore */
634         rc = 0;
635     }
636     else
637     {
638         rc = VCursorOpenRowRead ( & self -> dad );
639     }
640 
641     return rc;
642 }
643 
644 rc_t
VViewCursorCloseRow(const VViewCursor * p_self)645 VViewCursorCloseRow ( const VViewCursor * p_self )
646 {
647     VViewCursor * self = ( VViewCursor * ) p_self;
648 
649     if ( self -> dad . state == vcRowOpen )
650     {
651         return VCursorCloseRowRead ( & self -> dad );
652     }
653 
654     return 0;
655 }
656 
657 static
658 rc_t
VViewCursorGetBlobDirectInt(const VViewCursor * p_self,const VBlob ** p_blob,int64_t p_row_id,uint32_t p_col_idx)659 VViewCursorGetBlobDirectInt ( const VViewCursor *   p_self,
660                               const VBlob **        p_blob,
661                               int64_t               p_row_id,
662                               uint32_t              p_col_idx )
663 {
664     const VColumn *col = ( const VColumn* ) VectorGet ( & p_self -> dad . row, p_col_idx );
665     if ( col == NULL )
666     {
667         return RC ( rcVDB, rcCursor, rcReading, rcColumn, rcInvalid );
668     }
669     else
670     {
671         const void * base;
672         uint32_t elem_bits, boff, row_len;
673         VBlob * blob;
674         rc_t rc = VColumnRead ( col, p_self -> dad . row_id, & elem_bits, & base, & boff, & row_len, & blob );
675         if ( rc == 0 )
676         {
677             rc = VBlobAddRef ( blob );
678             if ( rc == 0 )
679             {
680                 * p_blob = blob;
681                 return 0;
682             }
683         }
684         return rc;
685     }
686 }
687 
688 rc_t
VViewCursorGetBlob(const VViewCursor * p_self,const VBlob ** p_blob,uint32_t p_col_idx)689 VViewCursorGetBlob ( const VViewCursor * p_self, const VBlob ** p_blob, uint32_t p_col_idx )
690 {
691     rc_t rc;
692 
693     if ( p_blob == NULL )
694     {
695         rc = RC ( rcVDB, rcCursor, rcAccessing, rcParam, rcNull );
696     }
697     else
698     {
699         switch ( p_self -> dad . state )
700         {
701         case vcConstruct:
702             rc = RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
703             break;
704         case vcReady:
705             rc = RC ( rcVDB, rcCursor, rcReading, rcRow, rcNotOpen );
706             break;
707         case vcRowOpen:
708             return VViewCursorGetBlobDirectInt ( p_self, p_blob, p_self -> dad . row_id, p_col_idx );
709         default:
710             rc = RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
711             break;
712         }
713 
714         * p_blob = NULL;
715     }
716     return rc;
717 }
718 
719 rc_t
VViewCursorGetBlobDirect(const VViewCursor * p_self,const VBlob ** p_blob,int64_t p_row_id,uint32_t p_col_idx)720 VViewCursorGetBlobDirect ( const VViewCursor * p_self,
721                            const VBlob **  p_blob,
722                            int64_t         p_row_id,
723                            uint32_t        p_col_idx )
724 {
725     rc_t rc;
726 
727     if ( p_blob == NULL )
728     {
729         rc = RC ( rcVDB, rcCursor, rcAccessing, rcParam, rcNull );
730     }
731     else
732     {
733         switch ( p_self -> dad . state )
734         {
735         case vcConstruct:
736             rc = RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
737             break;
738         case vcReady:
739         case vcRowOpen:
740             return VViewCursorGetBlobDirectInt ( p_self, p_blob, p_row_id, p_col_idx );
741         default:
742             rc = RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
743             break;
744         }
745 
746         * p_blob = NULL;
747     }
748     return rc;
749 }
750 
751 static __inline__
752 bool
bad_elem_bits(uint32_t elem_size,uint32_t elem_bits)753 bad_elem_bits ( uint32_t elem_size, uint32_t elem_bits )
754 {
755     if ( elem_size != elem_bits )
756     {
757         if ( elem_size < elem_bits && elem_bits % elem_size != 0 )
758             return true;
759         return ( elem_size % elem_bits != 0 );
760     }
761     return false;
762 }
763 
764 static
765 rc_t
CopyCell(uint32_t p_elem_size,uint32_t p_elem_bits,const void * p_src,uint32_t p_src_off,void * p_dest,uint32_t p_dest_len,uint32_t * p_row_len)766 CopyCell ( uint32_t     p_elem_size,
767            uint32_t     p_elem_bits,
768            const void * p_src,
769            uint32_t     p_src_off,
770            void *       p_dest,
771            uint32_t     p_dest_len,
772            uint32_t *   p_row_len )
773 {
774     rc_t rc = 0;
775     if ( bad_elem_bits ( p_elem_size, p_elem_bits ) )
776     {
777         rc = RC ( rcVDB, rcCursor, rcReading, rcType, rcInconsistent );
778     }
779     else if ( * p_row_len != 0 )
780     {
781         if ( p_dest_len == 0 )
782         {
783             rc = RC ( rcVDB, rcCursor, rcReading, rcBuffer, rcInsufficient );
784         }
785         if ( p_dest == NULL )
786         {
787             rc = RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
788         }
789         else
790         {
791             uint64_t to_read = * p_row_len * p_elem_size;
792             uint64_t bsize = p_dest_len * p_elem_bits;
793 
794             /* always return the required buffer size */
795             * p_row_len = ( uint32_t ) ( to_read / p_elem_bits );
796 
797             /* detect buffer too small */
798             if ( to_read > bsize )
799             {
800                 rc = RC ( rcVDB, rcCursor, rcReading, rcBuffer, rcInsufficient );
801                 to_read = bsize;
802             }
803 
804             /* copy out data up to limit */
805             assert ( p_src_off == 0 );
806             memmove ( p_dest, p_src, ( size_t ) ( to_read >> 3 ) );
807         }
808     }
809     return rc;
810 }
811 
812 static
813 rc_t
VViewCursorReadInt(const VViewCursor * p_self,int64_t p_row_id,uint32_t p_col_idx,uint32_t p_elem_bits,void * p_buffer,uint32_t p_blen,uint32_t * p_row_len)814 VViewCursorReadInt ( const VViewCursor *  p_self,
815                      int64_t              p_row_id,
816                      uint32_t             p_col_idx,
817                      uint32_t             p_elem_bits,
818                      void *               p_buffer,
819                      uint32_t             p_blen,
820                      uint32_t *           p_row_len )
821 {
822     rc_t rc;
823 
824     if ( p_row_len == NULL )
825     {
826         rc = RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
827     }
828     else
829     {
830         if ( p_elem_bits == 0 || ( p_elem_bits & 7 ) != 0 )
831         {
832             rc = RC ( rcVDB, rcCursor, rcReading, rcParam, rcInvalid );
833         }
834         else
835         {
836             const VColumn * col = ( const VColumn * ) VectorGet ( & p_self -> dad . row, p_col_idx );
837             if ( col != NULL )
838             {
839                 uint32_t elem_size;
840                 const void *base;
841                 uint32_t boff;
842                 rc = VColumnRead ( col, p_row_id, & elem_size, & base, & boff, p_row_len, NULL );
843                 if ( rc == 0 )
844                 {
845                     return CopyCell ( elem_size, p_elem_bits, base, boff, p_buffer, p_blen, p_row_len );
846                 }
847             }
848             else
849             {
850                 return RC ( rcVDB, rcCursor, rcReading, rcColumn, rcInvalid );
851             }
852         }
853     }
854     return rc;
855 }
856 
857 rc_t
VViewCursorRead(const VViewCursor * p_self,uint32_t p_col_idx,uint32_t p_elem_bits,void * p_buffer,uint32_t p_blen,uint32_t * p_row_len)858 VViewCursorRead ( const VViewCursor * p_self,
859                   uint32_t             p_col_idx,
860                   uint32_t             p_elem_bits,
861                   void *               p_buffer,
862                   uint32_t             p_blen,
863                   uint32_t *           p_row_len )
864 {
865     if ( p_row_len == NULL )
866     {
867         return RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
868     }
869     else
870     {
871         * p_row_len = 0;
872         switch ( p_self -> dad . state )
873         {
874         case vcConstruct:
875             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
876         case vcReady:
877             return RC ( rcVDB, rcCursor, rcReading, rcRow, rcNotOpen );
878         case vcRowOpen:
879             return VViewCursorReadInt ( p_self, p_self -> dad . row_id, p_col_idx, p_elem_bits, p_buffer, p_blen, p_row_len);
880         default:
881             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
882         }
883     }
884 }
885 
VViewCursorReadDirect(const VViewCursor * p_self,int64_t p_row_id,uint32_t p_col_idx,uint32_t p_elem_bits,void * p_buffer,uint32_t p_blen,uint32_t * p_row_len)886 static rc_t VViewCursorReadDirect ( const VViewCursor *    p_self,
887                                     int64_t                 p_row_id,
888                                     uint32_t                p_col_idx,
889                                     uint32_t                p_elem_bits,
890                                     void *                  p_buffer,
891                                     uint32_t                p_blen,
892                                     uint32_t *              p_row_len )
893 {
894     if ( p_row_len == NULL )
895     {
896         return RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
897     }
898     else
899     {
900         * p_row_len = 0;
901         switch ( p_self -> dad . state )
902         {
903         case vcConstruct:
904             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
905         case vcReady:
906         case vcRowOpen:
907             return VViewCursorReadInt ( p_self, p_row_id, p_col_idx, p_elem_bits, p_buffer, p_blen, p_row_len);
908         default:
909             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
910         }
911     }
912 }
913 
914 static
915 rc_t
CopyRowBits(uint32_t p_elem_size,uint32_t p_elem_bits,uint32_t p_start,const void * p_src,uint32_t p_src_off,void * p_dest,uint32_t p_off,uint32_t p_dest_len,uint32_t * p_num_read,uint32_t * p_remaining)916 CopyRowBits ( uint32_t      p_elem_size,
917               uint32_t      p_elem_bits,
918               uint32_t      p_start,
919               const void *  p_src,
920               uint32_t      p_src_off,
921               void *        p_dest,
922               uint32_t      p_off,
923               uint32_t      p_dest_len,
924               uint32_t *    p_num_read,
925               uint32_t *    p_remaining )
926 {
927     rc_t rc = 0;
928     if ( bad_elem_bits ( p_elem_size, p_elem_bits ) )
929     {
930         rc = RC ( rcVDB, rcCursor, rcReading, rcType, rcInconsistent );
931     }
932     else if ( * p_num_read != 0 )
933     {
934         uint64_t to_read = * p_num_read * p_elem_size;
935         uint64_t doff = p_start * p_elem_bits;
936         to_read = to_read > doff ? to_read - doff : 0;
937         if ( p_dest_len == 0 )
938         {
939             * p_num_read = 0;
940             * p_remaining = ( uint32_t ) ( to_read / p_elem_bits );
941             return 0;
942         }
943 
944         if ( p_dest == NULL )
945         {
946             rc = RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
947         }
948         else
949         {
950             uint64_t bsize = p_dest_len * p_elem_size;
951             if ( to_read <= bsize )
952             {
953                 * p_remaining = 0;
954             }
955             else
956             {
957                 * p_remaining = (uint32_t)( ( to_read - bsize ) / p_elem_bits );
958                 to_read = bsize;
959             }
960             bitcpy ( p_dest, p_off, p_src, p_src_off + doff, ( bitsz_t ) to_read );
961             * p_num_read = ( uint32_t ) ( to_read / p_elem_bits );
962             return 0;
963         }
964     }
965     return rc;
966 }
967 
968 static
969 rc_t
VViewCursorReadBitsInt(const VViewCursor * p_self,uint32_t p_row_id,uint32_t p_col_idx,uint32_t p_elem_bits,uint32_t p_start,void * p_buffer,uint32_t p_off,uint32_t p_blen,uint32_t * p_num_read,uint32_t * p_remaining)970 VViewCursorReadBitsInt ( const VViewCursor *  p_self,
971                          uint32_t              p_row_id,
972                          uint32_t              p_col_idx,
973                          uint32_t              p_elem_bits,
974                          uint32_t              p_start,
975                          void *                p_buffer,
976                          uint32_t              p_off,
977                          uint32_t              p_blen,
978                          uint32_t *            p_num_read,
979                          uint32_t *            p_remaining )
980 {
981     rc_t rc;
982 
983     if ( p_elem_bits == 0 )
984     {
985         rc = RC ( rcVDB, rcCursor, rcReading, rcParam, rcInvalid );
986     }
987     else
988     {
989         const VColumn * col;
990 
991         col = ( const VColumn * ) VectorGet ( & p_self -> dad . row, p_col_idx );
992         if ( col != NULL )
993         {
994             uint32_t elem_size;
995             const void *base;
996             uint32_t boff;
997             rc = VColumnRead ( col, p_row_id, & elem_size, & base, & boff, p_num_read, NULL );
998             if ( rc == 0 )
999             {
1000                 return CopyRowBits ( elem_size, p_elem_bits, p_start, base, boff, p_buffer, p_off, p_blen, p_num_read, p_remaining );
1001             }
1002         }
1003         else
1004         {
1005             return RC ( rcVDB, rcCursor, rcReading, rcColumn, rcInvalid );
1006         }
1007     }
1008     return rc;
1009 }
1010 
1011 rc_t
VViewCursorReadBits(const VViewCursor * p_self,uint32_t p_col_idx,uint32_t p_elem_bits,uint32_t p_start,void * p_buffer,uint32_t p_off,uint32_t p_blen,uint32_t * p_num_read,uint32_t * p_remaining)1012 VViewCursorReadBits ( const VViewCursor *    p_self,
1013                       uint32_t                p_col_idx,
1014                       uint32_t                p_elem_bits,
1015                       uint32_t                p_start,
1016                       void *                  p_buffer,
1017                       uint32_t                p_off,
1018                       uint32_t                p_blen,
1019                       uint32_t *              p_num_read,
1020                       uint32_t *              p_remaining )
1021 {
1022     if ( p_num_read == NULL )
1023     {
1024         return RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
1025     }
1026     else
1027     {
1028         uint32_t dummy;
1029         if ( p_remaining == NULL )
1030         {
1031             p_remaining = & dummy;
1032         }
1033         * p_num_read = 0;
1034         * p_remaining = 0;
1035 
1036         switch ( p_self -> dad . state )
1037         {
1038         case vcConstruct:
1039             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
1040         case vcReady:
1041             return RC ( rcVDB, rcCursor, rcReading, rcRow, rcNotOpen );
1042         case vcRowOpen:
1043             return VViewCursorReadBitsInt ( p_self, p_self -> dad . row_id, p_col_idx, p_elem_bits, p_start, p_buffer, p_off, p_blen, p_num_read, p_remaining);
1044         default:
1045             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
1046         }
1047     }
1048 }
1049 
1050 rc_t
VViewCursorReadBitsDirect(const VViewCursor * p_self,int64_t p_row_id,uint32_t p_col_idx,uint32_t p_elem_bits,uint32_t p_start,void * p_buffer,uint32_t p_off,uint32_t p_blen,uint32_t * p_num_read,uint32_t * p_remaining)1051 VViewCursorReadBitsDirect ( const VViewCursor *    p_self,
1052                             int64_t                 p_row_id,
1053                             uint32_t                p_col_idx,
1054                             uint32_t                p_elem_bits,
1055                             uint32_t                p_start,
1056                             void *                  p_buffer,
1057                             uint32_t                p_off,
1058                             uint32_t                p_blen,
1059                             uint32_t *              p_num_read,
1060                             uint32_t *              p_remaining )
1061 {
1062     if ( p_num_read == NULL )
1063     {
1064         return RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
1065     }
1066     else
1067     {
1068         uint32_t dummy;
1069         if ( p_remaining == NULL )
1070         {
1071             p_remaining = & dummy;
1072         }
1073         * p_num_read = 0;
1074         * p_remaining = 0;
1075 
1076         switch ( p_self -> dad . state )
1077         {
1078         case vcConstruct:
1079             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
1080         case vcReady:
1081         case vcRowOpen:
1082             return VViewCursorReadBitsInt ( p_self, p_row_id, p_col_idx, p_elem_bits, p_start, p_buffer, p_off, p_blen, p_num_read, p_remaining);
1083         default:
1084             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
1085         }
1086     }
1087 }
1088 
1089 static
1090 rc_t
VViewCursorCellDataInt(const VViewCursor * p_self,int64_t p_row_id,uint32_t p_col_idx,uint32_t * p_elem_bits,const void ** p_base,uint32_t * p_boff,uint32_t * p_row_len)1091 VViewCursorCellDataInt ( const VViewCursor *  p_self,
1092                          int64_t               p_row_id,
1093                          uint32_t              p_col_idx,
1094                          uint32_t *            p_elem_bits,
1095                          const void **         p_base,
1096                          uint32_t *            p_boff,
1097                          uint32_t *            p_row_len )
1098 {
1099     rc_t rc;
1100     const VColumn * col;
1101 
1102     uint32_t dummy [ 3 ];
1103     if ( p_row_len == NULL )
1104     {
1105         p_row_len = & dummy [ 0 ];
1106     }
1107     if ( p_boff == NULL )
1108     {
1109         p_boff = & dummy [ 1 ];
1110     }
1111     if ( p_elem_bits == NULL )
1112     {
1113         p_elem_bits = & dummy [ 2 ];
1114     }
1115 
1116     col = ( const VColumn * ) VectorGet ( & p_self -> dad . row, p_col_idx );
1117     if ( col != NULL )
1118     {
1119         rc = VColumnRead ( col, p_row_id, p_elem_bits, p_base, p_boff, p_row_len, NULL );
1120         if ( rc == 0 )
1121         {
1122             return 0;
1123         }
1124     }
1125     else
1126     {
1127         rc = RC ( rcVDB, rcCursor, rcReading, rcColumn, rcInvalid );
1128     }
1129 
1130     * p_elem_bits = 0;
1131     * p_boff = 0;
1132     * p_row_len = 0;
1133 
1134     return rc;
1135 }
1136 
1137 rc_t
VViewCursorCellData(const VViewCursor * p_self,uint32_t p_col_idx,uint32_t * p_elem_bits,const void ** p_base,uint32_t * p_boff,uint32_t * p_row_len)1138 VViewCursorCellData ( const VViewCursor *  p_self,
1139                       uint32_t              p_col_idx,
1140                       uint32_t *            p_elem_bits,
1141                       const void **         p_base,
1142                       uint32_t *            p_boff,
1143                       uint32_t *            p_row_len )
1144 {
1145     if ( p_base == NULL )
1146     {
1147         return RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
1148     }
1149     else
1150     {
1151         * p_base = NULL;
1152 
1153         switch ( p_self -> dad . state )
1154         {
1155         case vcConstruct:
1156             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
1157         case vcReady:
1158             return RC ( rcVDB, rcCursor, rcReading, rcRow, rcNotOpen );
1159         case vcRowOpen:
1160             return VViewCursorCellDataInt ( p_self, p_self -> dad . row_id, p_col_idx, p_elem_bits, p_base, p_boff, p_row_len);
1161         default:
1162             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
1163         }
1164     }
1165 }
1166 
1167 rc_t
VViewCursorCellDataDirect(const VViewCursor * p_self,int64_t p_row_id,uint32_t p_col_idx,uint32_t * p_elem_bits,const void ** p_base,uint32_t * p_boff,uint32_t * p_row_len)1168 VViewCursorCellDataDirect ( const VViewCursor *    p_self,
1169                             int64_t                 p_row_id,
1170                             uint32_t                p_col_idx,
1171                             uint32_t *              p_elem_bits,
1172                             const void **           p_base,
1173                             uint32_t *              p_boff,
1174                             uint32_t *              p_row_len )
1175 {
1176     if ( p_base == NULL )
1177     {
1178         return RC ( rcVDB, rcCursor, rcReading, rcParam, rcNull );
1179     }
1180     else
1181     {
1182         * p_base = NULL;
1183 
1184         switch ( p_self -> dad . state )
1185         {
1186         case vcConstruct:
1187             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcNotOpen );
1188         case vcReady:
1189         case vcRowOpen:
1190             return VViewCursorCellDataInt ( p_self, p_row_id, p_col_idx, p_elem_bits, p_base, p_boff, p_row_len);
1191         default:
1192             return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcInvalid );
1193         }
1194     }
1195 }
1196 
1197 rc_t
VViewCursorDataPrefetch(const VViewCursor * p_cself,const int64_t * p_row_ids,uint32_t p_col_idx,uint32_t p_num_rows,int64_t p_min_valid_row_id,int64_t p_max_valid_row_id,bool p_continue_on_error)1198 VViewCursorDataPrefetch ( const VViewCursor *  p_cself,
1199                           const int64_t *       p_row_ids,
1200                           uint32_t              p_col_idx,
1201                           uint32_t              p_num_rows,
1202                           int64_t               p_min_valid_row_id,
1203                           int64_t               p_max_valid_row_id,
1204                           bool                  p_continue_on_error )
1205 {
1206     return 0;
1207 }
1208 
1209 rc_t
VViewCursorOpenParentRead(const VViewCursor * p_self,const VTable ** p_tbl)1210 VViewCursorOpenParentRead ( const VViewCursor * p_self, const VTable ** p_tbl )
1211 {
1212     rc_t rc;
1213 
1214     if ( p_tbl == NULL )
1215     {
1216         rc = RC ( rcVDB, rcCursor, rcAccessing, rcParam, rcNull );
1217     }
1218     else
1219     {
1220         const VTable * tbl = VViewCursorGetTable ( p_self );
1221         rc = VTableAddRef ( tbl );
1222         if ( rc == 0 )
1223         {
1224             * p_tbl = tbl;
1225             return 0;
1226         }
1227 
1228         * p_tbl = NULL;
1229     }
1230 
1231     return rc;
1232 }
1233 
VViewCursorFindOverride(const VViewCursor * p_self,const struct VCtxId * p_cid)1234 const KSymbol * VViewCursorFindOverride ( const VViewCursor * p_self, const struct VCtxId * p_cid )
1235 {
1236     return SViewFindOverride ( p_self -> view -> sview, p_cid );
1237 }
1238 
VViewCursorPermitPostOpenAdd(const VViewCursor * self)1239 rc_t VViewCursorPermitPostOpenAdd ( const VViewCursor * self )
1240 {
1241     return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcUnsupported );
1242 }
1243 
VViewCursorLinkedCursorGet(const VViewCursor * cself,const char * tbl,struct VCursor const ** curs)1244 rc_t VViewCursorLinkedCursorGet ( const VViewCursor *cself,const char *tbl, struct VCursor const **curs)
1245 {
1246     return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcUnsupported );
1247 }
VViewCursorLinkedCursorSet(const VViewCursor * cself,const char * tbl,struct VCursor const * curs)1248 rc_t VViewCursorLinkedCursorSet ( const VViewCursor *cself,const char *tbl, struct VCursor const *curs)
1249 {
1250     return RC ( rcVDB, rcCursor, rcReading, rcCursor, rcUnsupported );
1251 }
1252 
VViewCursorSetCacheCapacity(VViewCursor * self,uint64_t capacity)1253 uint64_t VViewCursorSetCacheCapacity ( VViewCursor *self,uint64_t capacity)
1254 {
1255     return 0;
1256 }
VViewCursorGetCacheCapacity(const VViewCursor * self)1257 uint64_t VViewCursorGetCacheCapacity ( const VViewCursor *self)
1258 {
1259     return 0;
1260 }
1261 
VViewCursorLaunchPagemapThread(struct VViewCursor * self)1262 rc_t VViewCursorLaunchPagemapThread ( struct VViewCursor *self )
1263 {
1264     return 0;
1265 }
VViewCursorPageMapProcessRequest(const struct VViewCursor * self)1266 const PageMapProcessRequest* VViewCursorPageMapProcessRequest ( const struct VViewCursor *self )
1267 {
1268     return NULL;
1269 }
1270 
VViewCursorCacheActive(const struct VViewCursor * self,int64_t * cache_empty_end)1271 bool VViewCursorCacheActive ( const struct VViewCursor * self, int64_t * cache_empty_end )
1272 {
1273     if ( cache_empty_end != NULL )
1274     {
1275         * cache_empty_end = 0;
1276     }
1277     return false;
1278 }
1279 
1280 // not implemented for views (read-only)
VViewCursorWrite(VViewCursor * p_self,uint32_t col_idx,bitsz_t elem_bits,const void * buffer,bitsz_t boff,uint64_t count)1281 rc_t VViewCursorWrite ( VViewCursor * p_self, uint32_t col_idx, bitsz_t elem_bits, const void *buffer, bitsz_t boff, uint64_t count )
1282 {
1283     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1284 }
VViewCursorCommitRow(VViewCursor * p_self)1285 rc_t VViewCursorCommitRow ( VViewCursor * p_self )
1286 {
1287     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1288 }
VViewCursorRepeatRow(VViewCursor * p_self,uint64_t count)1289 rc_t VViewCursorRepeatRow ( VViewCursor * p_self, uint64_t count )
1290 {
1291     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1292 }
VViewCursorFlushPage(VViewCursor * p_self)1293 rc_t VViewCursorFlushPage ( VViewCursor * p_self )
1294 {
1295     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1296 }
VViewCursorDefault(VViewCursor * p_self,uint32_t col_idx,bitsz_t elem_bits,const void * buffer,bitsz_t boff,uint64_t row_len)1297 rc_t VViewCursorDefault ( VViewCursor * p_self, uint32_t col_idx, bitsz_t elem_bits, const void *buffer, bitsz_t boff, uint64_t row_len )
1298 {
1299     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1300 }
VViewCursorCommit(VViewCursor * p_self)1301 rc_t VViewCursorCommit ( VViewCursor * p_self )
1302 {
1303     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1304 }
VViewCursorOpenParentUpdate(VViewCursor * p_self,VTable ** tbl)1305 rc_t VViewCursorOpenParentUpdate ( VViewCursor * p_self, VTable **tbl )
1306 {
1307     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1308 }
VViewCursorInstallTrigger(struct VViewCursor * self,struct VProduction * prod)1309 rc_t VViewCursorInstallTrigger ( struct VViewCursor * self, struct VProduction * prod )
1310 {
1311     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1312 }
VViewCursorSuspendTriggers(const VViewCursor * self)1313 rc_t VViewCursorSuspendTriggers ( const VViewCursor * self )
1314 {
1315     return RC ( rcVDB, rcCursor, rcWriting, rcCursor, rcReadonly );
1316 }
1317 
1318