Skip to content

Commit

Permalink
avoid recursion (#36)
Browse files Browse the repository at this point in the history
* avoid recursion, fix #35

* fix imports
  • Loading branch information
samuelcolvin authored Mar 1, 2022
1 parent 2d8d69e commit 18281d1
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 9 deletions.
12 changes: 12 additions & 0 deletions buildpg/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
'Values',
'MultipleValues',
'SetValues',
'JoinComponent',
)

NOT_WORD = re.compile(r'[^\w.*]', flags=re.A)
Expand Down Expand Up @@ -146,3 +147,14 @@ def render(self):
for k, v in iter_:
yield RawDangerous(', ')
yield from self._yield_pairs(k, v)


class JoinComponent(Component):
__slots__ = 'sep', 'items'

def __init__(self, items, sep=RawDangerous(', ')):
self.items = items
self.sep = sep

def render(self):
yield from yield_sep(self.items, self.sep)
6 changes: 2 additions & 4 deletions buildpg/funcs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from . import logic
from .components import JoinComponent


def AND(arg, *args):
Expand All @@ -16,10 +17,7 @@ def OR(arg, *args):


def comma_sep(arg, *args):
v = logic.as_sql_block(arg)
for a in args:
v = v.comma(a)
return v
return JoinComponent((arg,) + args)


def count(expr):
Expand Down
7 changes: 2 additions & 5 deletions buildpg/logic.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import Enum, unique
from typing import Union

from .components import Component, RawDangerous, VarLiteral, check_word, yield_sep
from .components import Component, JoinComponent, RawDangerous, VarLiteral, check_word, yield_sep

__all__ = ('LogicError', 'SqlBlock', 'Func', 'Not', 'Var', 'S', 'V', 'select_fields', 'Empty')

Expand Down Expand Up @@ -317,10 +317,7 @@ def __init__(self, v1, *, op: Operator = None, v2=None):


def select_fields(arg, *args):
v = as_var(arg)
for a in args:
v = v.comma(as_var(a))
return v
return JoinComponent([as_var(v) for v in (arg,) + args])


class Empty(SqlBlock):
Expand Down
10 changes: 10 additions & 0 deletions tests/test_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,13 @@ def test_simple_blocks(block, expected_query):
)
def test_block_repr(block, s):
assert s == repr(block())


def test_recursion():
# without JoinComponent this would cause a recursion error, see #35
values = [f'foo_{i}' for i in range(5000)]
query, query_args = render(':t', t=funcs.comma_sep(*values))

assert query.startswith('$1, $2')
assert query.endswith('$4998, $4999, $5000')
assert len(query_args) == 5000

0 comments on commit 18281d1

Please sign in to comment.