Class: ConceptQL::Nodes::Define

Inherits:
Node
  • Object
show all
Defined in:
lib/conceptql/nodes/define.rb

Overview

Mimics creating a variable name that stores an itermediate result as part of a larger concept

The idea is that a concept might be very complex and it helps to break that complex concept into a set of sub-concepts to better understand it.

Also, sometimes a particular piece of a concept is used in many places, so it makes sense to write that piece out once, store it as a “variable” and then insert that variable into the concept as needed. run the query once and subsequent calls

Constant Summary

Constants inherited from Node

Node::COLUMNS

Instance Attribute Summary

Attributes inherited from Node

#values

Instance Method Summary collapse

Methods inherited from Node

#arguments, #children, #evaluate, #select_it, #stream

Constructor Details

#initialize(*args) ⇒ Define

Returns a new instance of Define.



16
17
18
# File 'lib/conceptql/nodes/define.rb', line 16

def initialize(*args)
  super
end

Instance Method Details

#columns(query, local_type) ⇒ Object



59
60
61
# File 'lib/conceptql/nodes/define.rb', line 59

def columns(query, local_type)
  COLUMNS
end

#query(db) ⇒ Object

Create a temporary table and store the stream of results in that table. This “caches” the results so we only have to execute stream’s query once.

The logic here is that if something is assigned to a variable, chances are that it will be used more than once, so why run the query more than once?

ConceptQL’s SQL generator normally translates the entire statement into one, large query that can be executed later.

Unfortunately, Sequel’s “create_table” function actually executes the ‘CREATE TABLE’ SQL right away, meaning that the “define” node will execute immediately during the processing of the ConceptQL statement. We’ll see what kinds of problems this causes

Lastly, this node does NOT pass its results to the next node. The reason for this exception is to allow us to return the SQL that generates the temp table. This is done so that the ConceptQL sandbox can return the entire set of SQL statements needed to run a query.

Perhaps in the future we can find a way around this.

Also, things will blow up if you try to use a variable that hasn’t been defined yet.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/conceptql/nodes/define.rb', line 44

def query(db)
  # We'll wrap the creation of the temp table in memoization
  # That way we can call #query multiple times, but only suffer the
  # cost of creating the temp table just once
  @_run ||= begin
    if tree.opts[:sql_only]
      db.create_table!(table_name, temp: true, as: fake_row(db))
    else
      db.create_table!(table_name, temp: true, as: stream.evaluate(db))
    end
    true
  end
  db.from(table_name)
end

#sql(db) ⇒ Object



67
68
69
# File 'lib/conceptql/nodes/define.rb', line 67

def sql(db)
  db[db.send(:create_table_as_sql, table_name, stream.evaluate(db).sql, temp: true)].sql
end

#tree=(tree) ⇒ Object



71
72
73
74
# File 'lib/conceptql/nodes/define.rb', line 71

def tree=(tree)
  super
  tree.defined[table_name] = self
end

#typesObject



63
64
65
# File 'lib/conceptql/nodes/define.rb', line 63

def types
  stream.types
end