EvgSkv / logica

Logica is a logic programming language that compiles to SQL. It runs on Google BigQuery, PostgreSQL and SQLite.

Home Page:https://logica.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sqlite: whole row syntax gives error. "OperationalError: no such column"

RAbraham opened this issue · comments

Hi,

%%logica Engineers

@Engine("sqlite");

Employee(name: "Alice", role: "Product Manager");
Employee(name: "Bob", role: "Engineer");
Employee(name: "Caroline", role: "Engineer");
Employee(name: "David", role: "Data Scientist");
Employee(name: "Eve", role: "Data Scientist");

Engineers(..r) :- Employee(..r), r.role == "Engineer";  # <====== This fails
# Engineers(name:, role:) :- Employee(name:, role:) , role == "Engineer"  <===== This works
The following query is stored at Engineers_sql variable.
WITH t_0_Employee AS (SELECT * FROM (
  
    SELECT
      'Alice' AS name,
      'Product Manager' AS role
   UNION ALL
  
    SELECT
      'Bob' AS name,
      'Engineer' AS role
   UNION ALL
  
    SELECT
      'Caroline' AS name,
      'Engineer' AS role
   UNION ALL
  
    SELECT
      'David' AS name,
      'Data Scientist' AS role
   UNION ALL
  
    SELECT
      'Eve' AS name,
      'Data Scientist' AS role
  
) AS UNUSED_TABLE_NAME  )
SELECT
  Employee.*
FROM
  t_0_Employee AS Employee
WHERE
  (JSON_EXTRACT(Employee, "$.role") = 'Engineer');

Engineers

Running predicate: Engineers

---------------------------------------------------------------------------

OperationalError                          Traceback (most recent call last)

<ipython-input-19-db61baf7c59b> in <module>()
----> 1 get_ipython().run_cell_magic('logica', 'Engineers', '\n@Engine("sqlite");\n\nEmployee(name: "Alice", role: "Product Manager");\nEmployee(name: "Bob", role: "Engineer");\nEmployee(name: "Caroline", role: "Engineer");\nEmployee(name: "David", role: "Data Scientist");\nEmployee(name: "Eve", role: "Data Scientist");\n\nEngineers(..r) :- Employee(..r), r.role == "Engineer";\n# Engineers(name:, role:) :- Employee(name:, role:) , role == "Engineer"')

8 frames

/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
   2115             magic_arg_s = self.var_expand(line, stack_depth)
   2116             with self.builtin_trap:
-> 2117                 result = fn(magic_arg_s, cell)
   2118             return result
   2119 

/usr/local/lib/python3.7/dist-packages/logica/colab_logica.py in logica(line, cell)
    118 @register_cell_magic
    119 def logica(line, cell):
--> 120   Logica(line, cell, run_query=True)
    121 
    122 

/usr/local/lib/python3.7/dist-packages/logica/colab_logica.py in Logica(line, cell, run_query)
    239       sql_runner = RunSQL
    240     result_map = concertina_lib.ExecuteLogicaProgram(
--> 241       executions, sql_runner=sql_runner, sql_engine=engine)
    242 
    243   for idx, predicate in enumerate(predicates):

/usr/local/lib/python3.7/dist-packages/logica/common/concertina_lib.py in ExecuteLogicaProgram(logica_executions, sql_runner, sql_engine)
    215 
    216   concertina = Concertina(config, engine)
--> 217   concertina.Run()
    218   return engine.final_result

/usr/local/lib/python3.7/dist-packages/logica/common/concertina_lib.py in Run(self)
     76   def Run(self):
     77     while self.actions_to_run:
---> 78       self.RunOneAction()
     79 
     80   def ActionColor(self, a):

/usr/local/lib/python3.7/dist-packages/logica/common/concertina_lib.py in RunOneAction(self)
     69     self.running_actions |= {one_action}
     70     self.UpdateDisplay()
---> 71     self.engine.Run(self.action[one_action].get('action', {}))
     72     self.running_actions -= {one_action}
     73     self.complete_actions |= {one_action}

/usr/local/lib/python3.7/dist-packages/logica/common/concertina_lib.py in Run(self, action)
     18       print('Running predicate:', predicate)
     19       result = self.sql_runner(action['sql'], action['engine'],
---> 20                                is_final=(predicate in self.final_predicates))
     21       if predicate in self.final_predicates:
     22         self.final_result[predicate] = result

/usr/local/lib/python3.7/dist-packages/logica/colab_logica.py in __call__(self, sql, engine, is_final)
    159   # TODO: Sqlite runner should not be accepting an engine.
    160   def __call__(self, sql, engine, is_final):
--> 161     return RunSQL(sql, engine, self.connection, is_final)
    162 
    163 

/usr/local/lib/python3.7/dist-packages/logica/colab_logica.py in RunSQL(sql, engine, connection, is_final)
    142   elif engine == 'sqlite':
    143     statements = parse.SplitRaw(sql, ';')
--> 144     connection.executescript(sql)
    145     if is_final:
    146       return pandas.read_sql(statements[-1], connection)

OperationalError: no such column: Employee

I looked into this and it appears impossible to read whole table row as one object.
So this may have to be a long term behavior, we just need to document it.

We should also catch it and show a nice user error message.