New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: Fix subqueries with parameters #1303
Conversation
b607536
to
94bb3e2
Compare
10ca2ef
to
61c699d
Compare
3909737
to
6c4aee3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A short summary on top of ibis/sql/compiler.py
would be great, a general overview of the classes and the relationships between them.
It was pretty hard to understand the abstractions here when I wrote the clickhouse backend.
ibis/bigquery/client.py
Outdated
@@ -46,14 +55,30 @@ def __exit__(self, exc_type, exc_value, traceback): | |||
|
|||
class BigQuery(Query): | |||
|
|||
def __init__(self, *args, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about explicit args?
def __init__(self, client, ddl, params=None):
super(BigQuery, self).__init__(client, ddl)
self.query_parameters = params or []
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, will change. This originally was just so that I could do the default initialization and be robust to signature changes in the parent.
ibis/bigquery/client.py
Outdated
def __init__(self, *args, **kwargs): | ||
query_parameters = kwargs.pop('query_parameters', []) | ||
super(BigQuery, self).__init__(*args, **kwargs) | ||
self.query_parameters = query_parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might just hate typing but ibis.bigquery.BigQuery.query_parameters
is a bit verbose to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users don't interact with ibis at this level, and this is an instance variable anyway so the most you'd ever type is self.query_parameters
@@ -260,6 +245,13 @@ class BigQueryExprTranslator(impala_compiler.ImpalaExprTranslator): | |||
_registry = _operation_registry | |||
_rewrites = impala_compiler.ImpalaExprTranslator._rewrites.copy() | |||
|
|||
context_class = BigQueryContext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is inconsistent with the BigQuerySelect.translator
which is not postfixed with _class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's context_class
which is a class variable, and context
which is an instance of context_class
, so they are consistent, unless I'm misunderstanding you here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean BigQuerySelect.translator
is holding a class too: BigQueryExprTranslator
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll make a follow up issue to fix the inconsistency. In the meantime, I'm going to merge this next.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! :) You might check #1315 next
@@ -243,7 +234,8 @@ def execute(self, expr, params=None, limit='default', async=False): | |||
|
|||
def _execute_query(self, ddl, async=False): | |||
klass = self.async_query if async else self.sync_query | |||
return klass(self, ddl).execute() | |||
inst = klass(self, ddl) | |||
return inst.execute() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous one was nicer :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but this is +epsilon easier to debug.
context = self.context | ||
@property | ||
def translator(self): | ||
return self.context.dialect.translator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's quite hard to distinguish between Context, Dialect and Translator. Too many indirections for me.
What is the relationship between them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add some documentation for this in ibis/sql/compiler.py
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks :)
ff16f0b
to
0d5247e
Compare
ibis/bigquery/tests/test_client.py
Outdated
param = ibis.param('int64') | ||
expr = alltypes[alltypes.string_col.cast('int64') == param] | ||
|
||
string_value = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to change these names to reflect the actual values.
f8c7261
to
3330226
Compare
ibis/tests/backends.py
Outdated
@@ -57,6 +57,14 @@ def batting(self): | |||
def awards_players(self): | |||
return self.connection.database().awards_players | |||
|
|||
@classmethod | |||
def make_context(cls, params=None): | |||
module_name = cls.module |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a property for getting the module's name: self.name
We should use either explicit module variables or a method which converts the classname.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use either explicit module variables or a method which converts the classname.
I'm not sure I follow this. Isn't self.name
enough?
d02cca5
to
13f2f8d
Compare
f5f4042
to
eb285de
Compare
merging on green |
closes #1300
closes #1331
This was a somewhat invasive change, but nets a lot fewer places where the
params
argument has to be used outside of thecompile
andexecute
functions and methods on clients. Now,params
are part of thecontext
andcontext
is neverNone
so it's easier to reason about where parameters are coming from.