4 #include <RelationQuery.h>
7 static void RelationQuery_reclaim(Query *this) {
8 RelationQuery *q = (RelationQuery*) this;
13 // Make names have given values and return 1. If any name has a
14 // different value then return 0. Values are strings.
15 static int RelationQuery_next(
16 Query *this,BindingTable *bt,enum NextState state) {
17 RelationQuery *q = (RelationQuery*) this;
18 VectorIndex index = q->index + 1;
21 if ( q->saved == 0 ) {
22 q->saved = Tuple_clone( q->names );
24 memcpy( q->saved, q->names, q->names->size * sizeof( void* ) );
26 BindingTable_deref( bt, q->saved );
30 for ( ; index < q->rel->content.table.size; index++ ) {
31 Tuple *values = Relation_next( q->rel, &index, q->values );
34 BindingTable_set_all( bt, q->names, values, 1 );
40 BindingTable_set_all( bt, q->names, q->saved, 1 );
49 static void RelationQuery_variables(Query *this,HashVector *hv) {
50 RelationQuery *q = (RelationQuery*) this;
52 for ( i = 0; i < q->names->size; i++ ) {
53 HashVector_add( hv, q->names->elements[i] );
57 static struct QueryCallbacks RelationQuery_def = {
58 .reclaim = RelationQuery_reclaim,
59 .next = RelationQuery_next,
60 .variables = RelationQuery_variables
64 * Return a Query object representing an Relation of one or more
67 Query *Query_relation(Relation *r,Tuple *names,Tuple *values) {
68 RelationQuery *q = (RelationQuery*) malloc( sizeof( RelationQuery ) );
69 (*q) = (RelationQuery) {
70 .def = &RelationQuery_def,