Project

General

Profile

« Previous | Next » 

Revision 3918

sql_io.py: put_table(): is_literals: is_function: Fixed bug where function call needed to be recreated in each iteration of the main loop, because the arguments to the function, which are based on mapping, may change as the result of error handling replacing invalid values with NULL

View differences:

lib/sql_io.py
429 429
        insert_out_pkeys = insert_pkeys_table('out')
430 430
        insert_in_pkeys = insert_pkeys_table('in')
431 431
    
432
    if is_function:
432
    def mk_func_call():
433 433
        args = dict(((k.name, v) for k, v in mapping.iteritems()))
434 434
        func_call = sql_gen.NamedCol(out_pkey,
435 435
            sql_gen.FunctionCall(out_table, **args))
436
        return func_call, args
436 437
        
437
        if not is_literals:
438
            log_debug('Defining wrapper function')
439
            
440
            # Create empty pkeys table so its row type can be used
441
            insert_into_pkeys(input_joins, [in_pkey_col, func_call], limit=0,
442
                recover=True)
443
            result_type = db.col_info(sql_gen.Col(out_pkey, into)).type
444
            
445
            ## Create error handling wrapper function
446
            
447
            wrapper = db.TempFunction(sql_gen.concat(into.name, '_wrap'))
448
            
449
            select_cols = [in_pkey_col]+args.values()
450
            row_var = copy.copy(sql_gen.row_var)
451
            row_var.set_srcs([in_table])
452
            in_pkey_var = sql_gen.Col(in_pkey, row_var)
453
            
454
            args = dict(((k, sql_gen.with_table(v, row_var))
455
                for k, v in args.iteritems()))
456
            func_call = sql_gen.FunctionCall(out_table, **args)
457
            
458
            def mk_return(result):
459
                return sql_gen.ReturnQuery(sql.mk_select(db,
460
                    fields=[in_pkey_var, result], explain=False))
461
            exc_handler = func_wrapper_exception_handler(db,
462
                mk_return(sql_gen.Cast(result_type, None)), args.values(),
463
                errors_table_)
464
            
465
            sql.define_func(db, sql_gen.FunctionDef(wrapper,
466
                sql_gen.SetOf(into),
467
                sql_gen.RowExcIgnore(sql_gen.RowType(in_table),
468
                    sql.mk_select(db, input_joins, order_by=None),
469
                    mk_return(func_call), exc_handler=exc_handler)
470
                ))
471
            wrapper_table = sql_gen.FunctionCall(wrapper)
438
    if is_function and not is_literals:
439
        log_debug('Defining wrapper function')
440
        
441
        func_call, args = mk_func_call()
442
        
443
        # Create empty pkeys table so its row type can be used
444
        insert_into_pkeys(input_joins, [in_pkey_col, func_call], limit=0,
445
            recover=True)
446
        result_type = db.col_info(sql_gen.Col(out_pkey, into)).type
447
        
448
        ## Create error handling wrapper function
449
        
450
        wrapper = db.TempFunction(sql_gen.concat(into.name, '_wrap'))
451
        
452
        select_cols = [in_pkey_col]+args.values()
453
        row_var = copy.copy(sql_gen.row_var)
454
        row_var.set_srcs([in_table])
455
        in_pkey_var = sql_gen.Col(in_pkey, row_var)
456
        
457
        args = dict(((k, sql_gen.with_table(v, row_var))
458
            for k, v in args.iteritems()))
459
        func_call = sql_gen.FunctionCall(out_table, **args)
460
        
461
        def mk_return(result):
462
            return sql_gen.ReturnQuery(sql.mk_select(db,
463
                fields=[in_pkey_var, result], explain=False))
464
        exc_handler = func_wrapper_exception_handler(db,
465
            mk_return(sql_gen.Cast(result_type, None)), args.values(),
466
            errors_table_)
467
        
468
        sql.define_func(db, sql_gen.FunctionDef(wrapper, sql_gen.SetOf(into),
469
            sql_gen.RowExcIgnore(sql_gen.RowType(in_table),
470
                sql.mk_select(db, input_joins, order_by=None),
471
                mk_return(func_call), exc_handler=exc_handler)
472
            ))
473
        wrapper_table = sql_gen.FunctionCall(wrapper)
472 474
    
473 475
    # Do inserts and selects
474 476
    while True:
......
490 492
            break # don't do main case
491 493
        
492 494
        # Prepare to insert new rows
493
        if is_function: log_debug('Calling function on input rows')
495
        if is_function:
496
            log_debug('Calling function on input rows')
497
            if is_literals: func_call, args = mk_func_call()
494 498
        else:
495 499
            log_debug('Trying to insert new rows')
496 500
            insert_args = dict(recover=True, cacheable=False)

Also available in: Unified diff