Ejemplo n.º 1
0
    def schema_constraint_to_backend_constraint(cls, subject, constraint,
                                                schema):
        assert constraint.subject is not None

        ir = ql_compiler.compile_to_ir(constraint.finalexpr,
                                       schema,
                                       anchors={qlast.Subject: subject})

        terminal_refs = ir_utils.get_terminal_references(ir.expr.expr.result)
        ref_tables = cls._get_ref_storage_info(schema, terminal_refs)

        if len(ref_tables) > 1:
            raise ValueError(
                'backend: multi-table constraints are not currently supported')
        elif ref_tables:
            subject_db_name = next(iter(ref_tables))
        else:
            subject_db_name = common.scalar_name_to_domain_name(subject.name,
                                                                catenate=False)

        link_bias = ref_tables and next(iter(
            ref_tables.values()))[0][3].table_type == 'link'

        unique_expr_refs = cls._get_unique_refs(ir)

        pg_constr_data = {
            'subject_db_name': subject_db_name,
            'expressions': []
        }

        exprs = pg_constr_data['expressions']

        if unique_expr_refs:
            for ref in unique_expr_refs:
                exprdata = cls._edgeql_ref_to_pg_constr(
                    subject, ref, schema, link_bias)
                exprs.append(exprdata)

            pg_constr_data['scope'] = 'relation'
            pg_constr_data['type'] = 'unique'
            pg_constr_data['subject_db_name'] = subject_db_name
        else:
            exprdata = cls._edgeql_ref_to_pg_constr(subject, ir, schema,
                                                    link_bias)
            exprs.append(exprdata)

            pg_constr_data['subject_db_name'] = subject_db_name
            pg_constr_data['scope'] = 'row'
            pg_constr_data['type'] = 'check'

        if isinstance(constraint.subject, s_scalars.ScalarType):
            constraint = SchemaDomainConstraint(subject=subject,
                                                constraint=constraint,
                                                pg_constr_data=pg_constr_data)
        else:
            constraint = SchemaTableConstraint(subject=subject,
                                               constraint=constraint,
                                               pg_constr_data=pg_constr_data)
        return constraint
Ejemplo n.º 2
0
    def run_test(self, *, source, spec, expected):
        ir = compiler.compile_to_ir(source, self.schema)

        cardinality = irinference.infer_cardinality(ir, set(), self.schema)
        expected_cardinality = irast.Cardinality(
            textwrap.dedent(expected).strip(' \n'))
        self.assertEqual(cardinality, expected_cardinality,
                         'unexpected cardinality:\n' + source)
    def run_test(self, *, source, spec, expected):
        ir = compiler.compile_to_ir(source, self.schema)

        path_scope = textwrap.indent(ir.scope_tree.pformat(), '    ')
        expected_scope = textwrap.indent(
            textwrap.dedent(expected).strip(' \n'), '    ')

        if path_scope != expected_scope:
            diff = '\n'.join(
                difflib.context_diff(expected_scope.split('\n'),
                                     path_scope.split('\n')))

            self.fail(f'Scope tree does not match the expected result.'
                      f'\nEXPECTED:\n{expected_scope}\nACTUAL:\n{path_scope}'
                      f'\nDIFF:\n{diff}')
Ejemplo n.º 4
0
def ptr_default_to_col_default(schema, ptr, expr):
    try:
        ir = ql_compiler.compile_to_ir(expr, schema)
    except s_err.SchemaError:
        # Referene errors mean that is is a non-constant default
        # referring to a not-yet-existing objects.
        return None

    if not ir_utils.is_const(ir):
        return None

    sql_expr = compiler.compile_ir_to_sql_tree(
        ir, schema=schema, singleton_mode=True)
    sql_text = codegen.SQLSourceGenerator.to_source(sql_expr)

    return sql_text