You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2006/08/09 15:36:53 UTC
svn commit: r430051 - in /db/derby/code/trunk/java:
client/org/apache/derby/client/am/ client/org/apache/derby/client/net/
testing/org/apache/derbyTesting/functionTests/suites/
testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/
Author: rhillegas
Date: Wed Aug 9 06:36:51 2006
New Revision: 430051
URL: http://svn.apache.org/viewvc?rev=430051&view=rev
Log:
DERBY-694: Commit Narayanan's DERBY-694_v6.diff patch so that statement severity errors don't close jdbc objects which they shouldn't.
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ResultSetCloseTest.java (with props)
Modified:
db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/ConnectionCallbackInterface.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSetCallbackInterface.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCallbackInterface.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSetReply.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java Wed Aug 9 06:36:51 2006
@@ -1841,6 +1841,24 @@
}
inUnitOfWork_ = false;
}
+
+ /**
+ *
+ * Rollback the specific UnitOfWorkListener.
+ * @param uwl The UnitOfWorkLitener to be rolled back
+ *
+ */
+ public void completeSpecificRollback(UnitOfWorkListener uwl) {
+ java.util.Set keySet = CommitAndRollbackListeners_.keySet();
+ for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
+ UnitOfWorkListener listener = (UnitOfWorkListener) i.next();
+ if(listener == uwl) {
+ listener.completeLocalRollback(i);
+ break;
+ }
+ }
+ inUnitOfWork_ = false;
+ }
public abstract void writeLocalXARollback_() throws SqlException;
@@ -1868,6 +1886,16 @@
// Occurs autonomously
public void completeAbnormalUnitOfWork() {
completeLocalRollback();
+ }
+
+ /**
+ *
+ * Rollback the UnitOfWorkListener specifically.
+ * @param uwl The UnitOfWorkListener to be rolled back.
+ *
+ */
+ public void completeAbnormalUnitOfWork(UnitOfWorkListener uwl) {
+ completeSpecificRollback(uwl);
}
// Called by Connection.close(), NetConnection.errorRollbackDisconnect().
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ConnectionCallbackInterface.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ConnectionCallbackInterface.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ConnectionCallbackInterface.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ConnectionCallbackInterface.java Wed Aug 9 06:36:51 2006
@@ -36,4 +36,12 @@
public void completeChainBreakingDisconnect();
public void completeSqlca(Sqlca e);
+
+ /**
+ *
+ * Rollback the UnitOfWorkListener specifically.
+ * @param uwl The UnitOfWorkListener to be rolled back.
+ *
+ */
+ public void completeAbnormalUnitOfWork(UnitOfWorkListener uwl);
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Wed Aug 9 06:36:51 2006
@@ -30,8 +30,7 @@
import org.apache.derby.shared.common.i18n.MessageUtil;
public abstract class ResultSet implements java.sql.ResultSet,
- ResultSetCallbackInterface,
- UnitOfWorkListener {
+ ResultSetCallbackInterface {
//---------------------navigational members-----------------------------------
public Statement statement_;
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSetCallbackInterface.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSetCallbackInterface.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSetCallbackInterface.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSetCallbackInterface.java Wed Aug 9 06:36:51 2006
@@ -26,7 +26,7 @@
//
// Reply implementations may update result set state via this interface.
-public interface ResultSetCallbackInterface {
+public interface ResultSetCallbackInterface extends UnitOfWorkListener {
// The query was ended at the server because all rows have been retrieved.
public void earlyCloseComplete(Sqlca sqlca);
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java Wed Aug 9 06:36:51 2006
@@ -25,7 +25,7 @@
import org.apache.derby.shared.common.reference.JDBC30Translation;
import org.apache.derby.shared.common.reference.SQLState;
-public class Statement implements java.sql.Statement, StatementCallbackInterface, UnitOfWorkListener {
+public class Statement implements java.sql.Statement, StatementCallbackInterface{
// JDBC 3 constant indicating that the current ResultSet object
// should be closed when calling getMoreResults.
@@ -2812,5 +2812,4 @@
{
return jdbc3FeatureNotSupported(true);
}
-
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCallbackInterface.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCallbackInterface.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCallbackInterface.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCallbackInterface.java Wed Aug 9 06:36:51 2006
@@ -29,7 +29,7 @@
// Reply implementations may update statement state via this interface.
//
-public interface StatementCallbackInterface {
+public interface StatementCallbackInterface extends UnitOfWorkListener {
// A query has been opened on the server.
public void completeOpenQuery(Sqlca sqlca, ResultSet resultSet) throws DisconnectException;
@@ -58,6 +58,4 @@
public ConnectionCallbackInterface getConnectionCallbackInterface();
public ColumnMetaData getGuessedResultSetMetaData();
-
-
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnectionReply.java Wed Aug 9 06:36:51 2006
@@ -25,12 +25,17 @@
import org.apache.derby.client.am.Connection;
import org.apache.derby.client.am.ConnectionCallbackInterface;
+import org.apache.derby.client.am.StatementCallbackInterface;
+import org.apache.derby.client.am.ResultSetCallbackInterface;
import org.apache.derby.client.am.DisconnectException;
import org.apache.derby.client.am.SqlException;
import org.apache.derby.client.am.ClientMessageId;
import org.apache.derby.client.am.Sqlca;
import java.io.UnsupportedEncodingException;
+import org.apache.derby.client.am.UnitOfWorkListener;
+import org.apache.derby.shared.common.error.ExceptionSeverity;
+import org.apache.derby.shared.common.error.ExceptionUtil;
import org.apache.derby.shared.common.reference.SQLState;
import org.apache.derby.shared.common.reference.MessageId;
import org.apache.derby.shared.common.i18n.MessageUtil;
@@ -343,7 +348,7 @@
int peekCP = peekCodePoint();
switch (peekCP) {
case CodePoint.ABNUOWRM:
- NetSqlca sqlca = parseAbnormalEndUow(connection);
+ NetSqlca sqlca = parseAbnormalEndUow(connection,null);
connection.completeSqlca(sqlca);
break;
case CodePoint.CMDCHKRM:
@@ -467,16 +472,58 @@
doObjnsprmSemantics(peekCP);
}
}
-
- NetSqlca parseAbnormalEndUow(ConnectionCallbackInterface connection) throws DisconnectException {
- parseABNUOWRM(connection);
+
+ /**
+ * Perform necessary actions for parsing of a ABNUOWRM message.
+ *
+ * @param connection an implementation of the ConnectionCallbackInterface
+ *
+ * @return an NetSqlca object obtained from parsing the ABNUOWRM
+ * @throws DisconnectException
+ *
+ */
+ NetSqlca parseAbnormalEndUow(ConnectionCallbackInterface connection,UnitOfWorkListener uwl) throws DisconnectException {
+ parseABNUOWRM();
if (peekCodePoint() != CodePoint.SQLCARD) {
parseTypdefsOrMgrlvlovrs();
}
NetSqlca netSqlca = parseSQLCARD(null);
+
+ if(ExceptionUtil.getSeverityFromIdentifier(netSqlca.getSqlState()) >
+ ExceptionSeverity.STATEMENT_SEVERITY || uwl == null)
+ connection.completeAbnormalUnitOfWork();
+ else
+ connection.completeAbnormalUnitOfWork(uwl);
+
return netSqlca;
}
+
+ /**
+ * Perform necessary actions for parsing of a ABNUOWRM message.
+ *
+ * @param connection an implementation of the StatementCallbackInterface
+ *
+ * @return an NetSqlca object obtained from parsing the ABNUOWRM
+ * @throws DisconnectException
+ *
+ */
+ NetSqlca parseAbnormalEndUow(StatementCallbackInterface s) throws DisconnectException {
+ return parseAbnormalEndUow(s.getConnectionCallbackInterface(),s);
+ }
+
+ /**
+ * Perform necessary actions for parsing of a ABNUOWRM message.
+ *
+ * @param connection an implementation of the ResultsetCallbackInterface
+ *
+ * @return an NetSqlca object obtained from parsing the ABNUOWRM
+ * @throws DisconnectException
+ *
+ */
+ NetSqlca parseAbnormalEndUow(ResultSetCallbackInterface r) throws DisconnectException {
+ return parseAbnormalEndUow(r.getConnectionCallbackInterface(),r);
+ }
void parseRdbAccessFailed(NetConnection netConnection) throws DisconnectException {
parseRDBAFLRM();
@@ -1713,7 +1760,7 @@
// RDBNAM - required
//
// Called by all the NET*Reply classes.
- void parseABNUOWRM(ConnectionCallbackInterface connection) throws DisconnectException {
+ void parseABNUOWRM() throws DisconnectException {
boolean svrcodReceived = false;
int svrcod = CodePoint.SVRCOD_INFO;
boolean rdbnamReceived = false;
@@ -1754,8 +1801,6 @@
// the abnuowrm has been received, do whatever state changes are necessary
netAgent_.setSvrcod(svrcod);
- connection.completeAbnormalUnitOfWork();
-
}
//--------------------- parse DDM Reply Data--------------------------------------
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSetReply.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSetReply.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSetReply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSetReply.java Wed Aug 9 06:36:51 2006
@@ -193,7 +193,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(resultSetI.getConnectionCallbackInterface());
+ //passing the ResultSetCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(resultSetI);
resultSetI.completeSqlca(sqlca);
break;
}
@@ -216,7 +219,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(resultSetI.getConnectionCallbackInterface());
+ //passing the ResultSetCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(resultSetI);
resultSetI.completeSqlca(sqlca);
break;
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java Wed Aug 9 06:36:51 2006
@@ -516,7 +516,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface());
+ //passing the StatementCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(statement);
statement.completeSqlca(sqlca);
break;
}
@@ -548,7 +551,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface());
+ //passing the StatementCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(statement);
statement.completeSqlca(sqlca);
break;
}
@@ -582,7 +588,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface());
+ //passing the StatementCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(statement);
statement.completeSqlca(sqlca);
break;
}
@@ -609,7 +618,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(statementI.getConnectionCallbackInterface());
+ //passing the StatementCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(statementI);
statementI.completeSqlca(sqlca);
break;
}
@@ -638,7 +650,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(statementI.getConnectionCallbackInterface());
+ //passing the StatementCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(statementI);
statementI.completeSqlca(sqlca);
break;
}
@@ -671,7 +686,10 @@
switch (peekCP) {
case CodePoint.ABNUOWRM:
{
- NetSqlca sqlca = parseAbnormalEndUow(statement.getConnectionCallbackInterface());
+ //passing the StatementCallbackInterface implementation will
+ //help in retrieving the the UnitOfWorkListener that needs to
+ //be rolled back
+ NetSqlca sqlca = parseAbnormalEndUow(statement);
statement.completeSqlca(sqlca);
break;
}
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude Wed Aug 9 06:36:51 2006
@@ -47,3 +47,6 @@
jdbcapi/checkDataSource30.java
jdbcapi/checkDataSource.java
jdbcapi/SURTest_ij.sql
+# Excluding ResultSetClose test since an exception in a statement results in all
+# the result sets associated with the connection closing
+jdbcapi/ResultSetCloseTest.junit
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall?rev=430051&r1=430050&r2=430051&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall Wed Aug 9 06:36:51 2006
@@ -29,3 +29,4 @@
jdbcapi/ScrollResultSetTest.junit
jdbcapi/URCoveringIndexTest.junit
jdbcapi/SURTest_ij.sql
+jdbcapi/ResultSetCloseTest.junit
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ResultSetCloseTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ResultSetCloseTest.java?rev=430051&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ResultSetCloseTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ResultSetCloseTest.java Wed Aug 9 06:36:51 2006
@@ -0,0 +1,135 @@
+/*
+
+ Derby - Class ResultSetCloseTest
+
+ Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.jdbcapi;
+
+import junit.framework.*;
+
+import org.apache.derbyTesting.functionTests.util.BaseJDBCTestCase;
+
+import java.sql.*;
+
+/**
+ * This class is used to test the fix for DERBY-694.
+ *
+ * A brief description of DERBY-694 (Got from the description in JIRA)
+ *
+ * 1) Autocommit off.
+ * 2) Have two prepared statements, calling executeQuery() on both
+ * 3) Gives two result sets. Can fetch data from both with next().
+ * 4) If one statement gets an exception (say, caused by a division by zero)
+ * 5) not only this statement's result set is closed, but also the other open
+ * resultset. This happens with the client driver, whereas in embedded mode,
+ * the other result set is unaffected by the exception in the first result set
+ * (as it should be).
+ *
+ */
+public class ResultSetCloseTest extends BaseJDBCTestCase {
+
+ Connection con = null;
+ Statement s = null;
+ PreparedStatement ps1 = null;
+ PreparedStatement ps2 = null;
+ ResultSet rs1 = null;
+ ResultSet rs2 = null;
+
+ /**
+ * Create the tables and the Connection and PreparedStatements that will
+ * be used in this test.
+ */
+ public void setUp()
+ throws SQLException {
+ con = getConnection();
+ con.setAutoCommit(false);
+
+ s = con.createStatement();
+
+ s.execute("create table t1 (a int)");
+
+ s.execute("insert into t1 values(1)");
+ s.execute("insert into t1 values(0)");
+ s.execute("insert into t1 values(2)");
+ s.execute("insert into t1 values(3)");
+
+ con.commit();
+
+ ps1 = con.prepareStatement("select * from t1");
+
+ ps2 = con.prepareStatement("select 10/a from t1");
+ }
+
+ /**
+ * Test that the occurence of the exception in one of the PreparedStatements
+ * does not result in the closure of the ResultSet associated with the other
+ * Prepared Statements.
+ *
+ * STEPS :
+ * 1) Execute the first PreparedStatement. This should not cause any
+ * SQLException.
+ * 2) Now execute the second PreparedStatement. This causes
+ * the expected Divide by zero exception.
+ * 3) Now access the first resultset again to ensure this is still open.
+ *
+ */
+ public void testResultSetDoesNotClose() throws SQLException {
+ rs1 = ps1.executeQuery();
+
+ try {
+ rs2 = ps2.executeQuery();
+ while(rs2.next());
+ } catch(SQLException sqle) {
+ //Do Nothing expected exception
+ }
+
+ while(rs1.next());
+
+ con.commit();
+ }
+
+ /**
+ * Destroy the objects used in this test.
+ */
+ public void tearDown()
+ throws SQLException {
+ if (con != null && !con.isClosed()) {
+ con.rollback();
+ con.close();
+ }
+
+ con = null;
+ }
+
+ /**
+ * Create the test with the given name.
+ *
+ * @param name name of the test.
+ */
+ public ResultSetCloseTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Create test suite for this test.
+ */
+ public static Test suite() {
+ return new TestSuite(ResultSetCloseTest.class,"ResultSetCloseTest suite");
+ }
+
+}
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ResultSetCloseTest.java
------------------------------------------------------------------------------
svn:eol-style = native